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

Posted

技术标签:

【中文标题】UICollectionView 必须使用非零布局参数初始化【英文标题】:UICollectionView must be initialized with a non-nil layout parameter 【发布时间】:2012-10-28 16:01:23 【问题描述】:

我是 UICollectionView 的新手,我正在学习在网上找到的教程,但我遇到了一个我无法弄清楚的错误。这里有一点上下文。

在调试器中,我可以看到正在发生以下情况:

numberOfSectionsInCollectionView: 被调用,我返回 1 collectionView:numberOfItemsInSection: 被调用,我返回模型的大小 (20) collectionView:layout:sizeForItemAtIndexPath: 为模型中的每个项目调用一次 collectionView:layout:insetForSectionAtIndex: 被调用

collectionView:cellForItemAtIndexPath: 被调用并在此行崩溃...

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];

出现此错误...

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'

当我在该行暂停执行并检查控制台时,似乎有一个布局......

(lldb) po collectionView.collectionViewLayout
(UICollectionViewLayout *) $4 = 0x07180fd0 <UICollectionViewFlowLayout: 0x7180fd0>

UICollectionView 是故事板中唯一一个场景的一部分。在 viewController.m 中没有以任何方式创建的其他 UICollectionViews。

有人有什么想法吗?

【问题讨论】:

当您使用 alloc/init 或 new 创建新的集合视图而不是在初始化时添加布局对象时会出现该错误。您是否在任何地方制作新的收藏视图? @jrturton 我不知道。 UICollectionView 是故事板中唯一一个场景的一部分。在 viewController.m 中没有以任何方式创建的 UICollectionViews。但话虽如此,而且作为集合视图的新手,我不确定布局在哪里与集合视图相关联。 【参考方案1】:

这对我有用:

UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [aFlowLayout setItemSize:CGSizeMake(200, 140)];
    [aFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
myCollectionViewController = [[MyCollectionViewController alloc]initWithCollectionViewLayout:flowLayout];

如果您以编程方式创建 UICollectionView,则需要布局。

【讨论】:

抱歉,不是这样。正如我在问题中提到的,这是来自情节提要,如控制台输出所示,集合视图有一个有效的布局。请参阅我的答案以了解问题所在。 是的,这也是必不可少的。您为单元分配了错误的类。【参考方案2】:

事实证明问题出在registerClass:。我有这个:

[self.collectionView registerClass:[UICollectionView class] 
        forCellWithReuseIdentifier:@"MyCell"];

但应该是这样的:

[self.collectionView registerClass:[UICollectionViewCell class] 
        forCellWithReuseIdentifier:@"MyCell"];

所以 dequeue 方法是创建 UICollectionView 而不是 UICollectionViewCell

【讨论】:

【参考方案3】:

如果您在 UICollectionViewController 中以编程方式制作集合视图控制器,请确保 UICollectionViewController init 方法使用 [super initWithCollectionViewLayout] 而不是 [super init],例如:

-(id) initWithImages:(NSArray *)pImages 
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setMinimumInteritemSpacing:0.0f];
    [layout setMinimumLineSpacing:0.0f];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    if (self = [super initWithCollectionViewLayout:layout]) 
        _images= [[NSArray alloc] initWithArray:pImages];
    
    return self;

发件人:UICollectionViewController Class Reference:Overview

【讨论】:

【参考方案4】:

我遇到了同样的问题,我的通过使用解决了

UICollectionViewFlowLayout *myLayout = [[UICollectionViewFlowLayout alloc]init];
[myLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[myLayout setMinimumInteritemSpacing:0.0f];
[myLayout setMinimumLineSpacing:0.0f];
UICollectionView *myCollectionView = [[UICollectionView alloc]initWithFrame:viewfame collectionViewLayout:myLayout];

而不是

UICollectionView *myCollectionView = [[UICollectionView alloc]initWithFrame:self.view.frame];
[myLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[myLayout setMinimumInteritemSpacing:0.0f];
[myLayout setMinimumLineSpacing:0.0f];
[myCollectionView setCollectionViewLayout:myLayout];

【讨论】:

【参考方案5】:

如果您的类是从 UICollectionViewController 继承的,或者您正在以编程方式创建 UICollectionView,那么在推送该类时,您可以像下面这样设置 collectionViewLayout

let homeViewController = HomeViewContoller(collectionViewLayout:UICollectionViewLayout())

【讨论】:

【参考方案6】:

在视图初始化之前,我在返回一个 itemSize 等于 self.view.bounds 的 UICollectionViewLayout 对象时遇到了这个问题。

【讨论】:

以上是关于UICollectionView 必须使用非零布局参数初始化的主要内容,如果未能解决你的问题,请参考以下文章

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

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“UICollectionView 必须使用非零布局参数初始化

UICollectionView如何从委托中重新加载数据

Swift 中的 UICollectionView 自定义布局

使用自定义布局重新加载 UICollectionView 会引发错误

在 numberOfItemsInSection 返回非零项目编号后未调用 UICollectionView cellForItemAtIndexPath