UICollectionView _createPreparedCellForItem中的断言失败

时间:2014-05-07 19:28:58

标签: ios7 uicollectionview uicollectionviewcell

编辑对于遇到此问题的任何人,我已经使用适合我的解决方案回答了我的问题,您可以在下面找到。

原始问题

我正在尝试构建一个包含两种类型单元格的双列多节UICollectionView。我的目标是有两个基本状态(每个部分):

  • 至少要显示一个项目
    • 显示至少一个表示该项目的单元格,其中每个单元格的宽度是整个CollectionView的一半
  • 没有要显示的项目
    • 显示一个特殊的单元格,表示空状态,其宽度是普通单元格的两倍(因此它占据了“行”的CollectionView的整个宽度)

我构建了我认为正确的设置,包括覆盖下面的CollectionViewDelegateFlowLayout方法:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return [self trueSectionCount:indexPath.section] > 0 ? CGSizeMake(kItemCellWidth, kItemCellHeight) : CGSizeMake(kItemCellEmptyWidth, kItemCellEmptyHeight);
}

返回一个匹配某些尺寸的合适尺寸,这些尺寸与两种状态的单元格相同。


我的问题如下:cellForItemAtIndexPath:方法中创建第一个单元格并随后返回后,将抛出断言失败,如下所示:

*** Assertion failure in -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:], /SourceCache/UIKit_Sim/UIKit-2935.137/UICollectionView.m:1289

在阅读some / other / questions类似主题后,我有一些理论。

我之前认为这与我使用两种不同尺寸的事实有关,但这不可能是正确的,因为我手动覆盖了上面所示的所需方法,而且我从来没有设置过我的itemSize对象的UICollectionViewFlowLayout属性。

我的另一个理论是,在使用UICollectionView注册我的笔尖/类时,这可能是由一些有趣的事情造成的。由于我有两个类可以在任何给定时间用于项目填充,以及我从UICollectionView.h中的注释中收集的内容,特别是行102-104,因此应该只有一个注册的类/ nib关联与观点。所以我注释掉了nib的注册,而不是在dequeueReusableCellWithReuseIdentifier:中调用cellForItemAtIndexPath,我只是将一个新的Cell初始化为nil然后允许我的逻辑从其适当的nib创建新的单元格,而不是允许CollectionView使用它自己的内部逻辑来尝试和出列或生成一个新单元格(我知道Apple最近在这方面将UICollectionViewUITableView区分开来。 。不幸的是,我仍然没有得到这个断言。

我的想法已经用完,我很想知道是否有人可以帮助我。如果有任何我可以错过的信息,请告诉我,我很乐意提供。

1 个答案:

答案 0 :(得分:2)

原始问题的解决方案

我已经弄明白问题是什么了。

基本上我的理论是正确的,这个问题源于注册要由CollectionView出列的笔尖。我 做的是注册两个不同的UICollectionView子类以便重复使用,这很好,除了我使用相同的恢复标识符,所以CollectionView不知道哪一个出列。我改变了我的代码来注册它们:

[self.collectionView registerNib:[UINib nibWithNibName:@"SomeItemCell" bundle:nil] forCellWithReuseIdentifier:CellIdentifier];
[self.collectionView registerNib:[UINib nibWithNibName:@"SomeEmptyItemCell" bundle:nil] forCellWithReuseIdentifier:EmptyCellIdentifier];

然后使用他们自己的标识符适当地使细胞出列:

if (there are items to show in this section)
{
    SomeItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    ... code ...
    return cell;
}
else
{
    SomeEmptyItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:EmptyCellIdentifier forIndexPath:indexPath];
    ... code ...
    return cell;
}

这确保CollectionView确切知道要使用哪个单元格。我在上面展示的大小调整方法也是正确的,如果你计划使用多个单元格,那么方法非常重要,可以使所有内容完美地协同工作。