UICollectionView *Assertion Failure* 未在 UICollectionViewCell 上应用属性
Posted
技术标签:
【中文标题】UICollectionView *Assertion Failure* 未在 UICollectionViewCell 上应用属性【英文标题】:UICollectionView *Assertion Failure* for not applying attributes on UICollectionViewCell 【发布时间】:2016-10-16 21:07:43 【问题描述】:我正在尝试执行以下操作:
A)关卡 1 已解锁(包含解锁关卡的背景图片)。
B) 2-20 级被锁定(包含另一个背景图像)。它们将在每个连续关卡完成后解锁。
最初,当我运行应用程序并转到我的UICollectionView
时,一切看起来都很好。当我玩关卡 1 并完成它时,我保存(通过 Core Data)数字 0 用于名为 levelLocked
的托管对象 NSNumber
,现在属于关卡 2(0 表示解锁,其他关卡 3-20 应该用 1) 锁定。
保存关卡是否锁定或解锁的过程有效。但是当我回到我的UICollectionView
时,我没有看到 2 级的物理变化(它仍然有锁的背景图像)。
此外,如果我在UICollectionView
之前返回ViewController
,然后重新输入UICollectionView
,应用程序崩溃并出现错误:
*** Assertion failure in -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:],
我的单元格似乎没有正确更新(我不知道如何正确重新加载数据)。我确实为解锁和锁定级别类型注册了自定义UICollectionViewCell
nib。我检查了所有的拼写(如果这是问题的话,第一次就不会起作用)。
这是生成单元格的代码。
static NSString *cellIdentifier = @"tortoiseCell";
static NSString *tortIdentifier = @"tortoiseLocked";
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *regular;
NSMutableArray *data = [self.dataArray objectAtIndex:indexPath.section];
NSString *cellData = [data objectAtIndex:indexPath.row];
NSMutableArray *ar = [self.lockArray objectAtIndex:indexPath.section];
NSNumber *arLocks = [ar objectAtIndex:indexPath.row];
if ([arLocks integerValue] == 0)
TortoiseCell *cell = (TortoiseCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[cell.buttonClick setTag:indexPath.row];
[cell.buttonClick setTitle:cellData forState:UIControlStateNormal];
[cell.buttonClick setBackgroundImage:[UIImage imageNamed:@"TortoiseLevels.png"]
forState:UIControlStateNormal];
[cell.buttonClick addTarget:self action:@selector(buttonPressedSoWhatNumber:)
forControlEvents:UIControlEventTouchUpInside];
cell.buttonClick.layer.masksToBounds = YES;
[cell addSubview:cell.buttonClick];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
regular = cell;
else if ([arLocks integerValue] == 1)
TortoiseLocked *lockCell = (TortoiseLocked *)[collectionView dequeueReusableCellWithReuseIdentifier:tortIdentifier forIndexPath:indexPath];
[lockCell.tortoiseLock setTag:indexPath.row];
[lockCell.tortoiseLock setBackgroundImage:[UIImage imageNamed:@"TortoiseLock.png"]
forState:UIControlStateNormal];
lockCell.tortoiseLock.layer.masksToBounds = YES;
[lockCell addSubview:lockCell.tortoiseLock];
lockCell.layer.shouldRasterize = YES;
lockCell.layer.rasterizationScale = [UIScreen mainScreen].scale;
regular = lockCell;
return regular;
让我知道你的想法。我正在使用带有 XCode 7.1.2 的 ios 8.1
【问题讨论】:
还有没有更多的例外文本?断言失败的原因应该有一个原因或解释 就像我在其他帖子中提到的,这是完整的断言失败消息:Assertion failure in -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:]
我立刻想到了几件事。首先,您正在向单元格添加子视图,但在重用单元格的情况下,您将添加额外的子视图。这些子视图应该是您的单元子类的一部分,您不需要在此处添加它们。其次,使用标签来捕获索引是脆弱的。最好在单元格和控制器之间实现一个协议,以便在点击单元格按钮时调用委托方法。委托方法接收单元格,然后您可以使用indexPathForCell
检索 indexPath。
解决这个问题的最流行的答案是使用重用标识符注册笔尖。我已经这样做了。
最后,这可能是你的问题,这段代码有可能返回nil
。由于您显式测试 0 和 1,因此任何其他值都将导致 nil
这会给您一个例外。将else if
更改为简单的else
看看会发生什么
【参考方案1】:
如果您的数组中的值既不是 0 也不是 1,您的 cellForItemAtIndexPath
可以返回 nil
。我怀疑这是正在发生的事情,然后集合视图出现断言失败,因为您已经给它 nil的一个细胞。
简单的解决方法是将else if
更改为else
,默认情况下这将导致“锁定”单元格。
您还可以添加一个新的 else
子句来记录错误并使用它来尝试诊断您没有得到 0/1 的原因。
【讨论】:
再次感谢,断言失败消失,应用不再崩溃。我必须对 Core Data 进行一些修改,以确保所有解锁的关卡都显示为数字字符串,而不仅仅是当前解锁的关卡。以上是关于UICollectionView *Assertion Failure* 未在 UICollectionViewCell 上应用属性的主要内容,如果未能解决你的问题,请参考以下文章
-[UICollectionView _endItemAnimations] 中的 UICollectionView 断言失败
如何滚动另一个 UICollectionView 下方的 UICollectionView?
UICollectionView 单元内部已加载,但 UICollectionView 未显示
UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]