ios-UICollectionView:必须使用非nil布局参数初始化

我通过代码添加了UICollectionView
现在,应用程序崩溃并显示以下消息:UICollectionView must be initialized with a non-nil layout parameter
您有解决的主意吗?
CollectionCellUICollectionViewCell的自定义类。

@property (nonatomic, strong) UICollectionView* collectionView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.collectionView = [[UICollectionView alloc]init];
    [self.collectionView registerClass:[CollectionCell class] forCellWithReuseIdentifier:@"cell"];
    UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.itemSize = CGSizeMake(100, 100);
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    [self.collectionView setCollectionViewLayout:flowLayout];

    self.collectionView.frame = CGRectMake(0, 60, 320, 500);
    self.collectionView.backgroundColor = [UIColor whiteColor];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.view addSubview:self.eventCollection];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CollectionCell* cell = [self.eventCollection dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.label.text = [NSString stringWithFormat:@"%d", indexPath.item];
    return cell;
}
kusumoto_teruya asked 2019-11-07T22:11:34Z
6个解决方案
72 votes

崩溃清楚地告诉您出了什么问题:

必须使用非nil布局参数初始化UICollectionView。

如果查看self.view.frame的文档,则会发现唯一的初始化程序是self.view.frame。此外,在该初始化程序的参数中,您将看到:

集合视图的框架矩形,以点为单位。 框架的原点与您计划在其中添加的超级视图有关。 该帧在初始化期间传递给超类。

布局

用于组织项目的布局对象。 集合视图存储对指定对象的强引用。 不能为零。

我已经加粗了重要部分。 您必须使用self.view.frame来初始化self.collectionView,并且必须将非nil UICollectionViewLayout对象传递给它。


解决此问题的一种方法就是简单地更改初始化的顺序:

UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(100, 100);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

请注意,在上面的示例中,我假定您要使用self.view.frame作为self.collectionView的框架。如果不是这种情况,请插入所需的任何框架。

ravron answered 2019-11-07T22:12:46Z
34 votes

Swift 3.0和Swift 4.0

UICollectionView

该应用程序在初始化UICollectionView时启动后便立即崩溃

像下面这样初始化(在UICollectionViewController之上)

let alarmCollectionView:UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()

在方法中(内部UICollectionViewController

layout.scrollDirection = UICollectionViewScrollDirection.vertical
alarmCollectionView.setCollectionViewLayout(layout, animated: true)
alarmCollectionView.delegate = self
alarmCollectionView.dataSource = self
alarmCollectionView.backgroundColor = UIColor.clear
self.addSubview(alarmCollectionView)

像这样初始化后工作正常,我正在使用自动布局,所以使用UICollectionViewController或使用自己的UICollectionView

UICollectionViewController

如果您使用的是UICollectionViewController而不是UICollectionView,则需要在初始化时添加布局

 let  testNavController:UINavigationController = UINavigationController.init()
 let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init() 
 let collectionView:UICollectionViewController = UICollectionViewController.init(collectionViewLayout:layout )              
 testNavController.pushViewController(collectionView, animated: true)
Koushik answered 2019-11-07T22:13:56Z
18 votes

莱利·阿夫隆(Riley Avron)的答案的快速版本

    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(100, 100)
    let collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: layout)
    self.view.addSubview(collectionView)
    collectionView.delegate   = self
    collectionView.dataSource = self
    collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")
William Hu answered 2019-11-07T22:14:22Z
1 votes

在斯威夫特

var collectionView: UICollectionView!
let layout = UICollectionViewFlowLayout()
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
layout.scrollDirection = .vertical
view.addSubview(collectionView)
Sourabh Kumbhar answered 2019-11-07T22:14:42Z
0 votes

不要setCollectionViewLayout喜欢此帖:

[self.collectionView setCollectionViewLayout:flowLayout];

尝试在初始化时设置:

[[UICollectionView alloc] initWithFrame:frame collectionViewLayout:defaultLayout];
Semyon answered 2019-11-07T22:15:14Z
0 votes

Swift 3.0,Swift 4.0和Swift 5.0

对我来说有用。

let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())

在方法中(在viewDidLoad内部)

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.scrollDirection = .horizontal
}
John Corder answered 2019-11-07T22:15:52Z
translate from https://stackoverflow.com:/questions/24288927/uicollectionview-must-be-initialized-with-a-non-nil-layout-parameter