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 上应用属性的主要内容,如果未能解决你的问题,请参考以下文章

[leetcode]Fruit Into Baskets

折叠UICollectionView

-[UICollectionView _endItemAnimations] 中的 UICollectionView 断言失败

如何滚动另一个 UICollectionView 下方的 UICollectionView?

UICollectionView 单元内部已加载,但 UICollectionView 未显示

UICollectionView 断言失败 -[UICollectionView _updateWithItems:tentativelyForReordering:]