使用 setCollectionViewLayout 会导致崩溃,说 layoutAttributesForItemAtIndexPath not found

Posted

技术标签:

【中文标题】使用 setCollectionViewLayout 会导致崩溃,说 layoutAttributesForItemAtIndexPath not found【英文标题】:Using setCollectionViewLayout leads to crash , says layoutAttributesForItemAtIndexPath not found 【发布时间】:2016-02-15 22:01:03 【问题描述】:

我有一个集合视图,我必须动态更改集合视图的布局。在设置新布局时,应用程序会因日志而崩溃,

2016-02-15 13:47:31.663 PhotoBoard[92347:5235792] *** 断言失败 -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit -3512.30.14/UICollectionViewData.m:666

2016-02-15 13:47:31.666 PhotoBoard[92347:5235792] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-layoutAttributesForItemAtIndexPath 没有 UICollectionViewLayoutAttributes 实例:length = 2, path = 0 - 0' * 首先抛出调用栈: ( 0 核心基础 0x000000010d94de65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010f8b5deb objc_exception_throw + 48 2 核心基础 0x000000010d94dcca +[NSException raise:format:arguments:] + 106 3 基础 0x000000010dfbe4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198 4 UIKit 0x000000010ec4161c-[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 627 5 UIKit 0x000000010ebeee24-[UICollectionView _setCollectionViewLayout:animated:isInteractive:completion:] + 1606 6 UIKit 0x000000010ebee4db -[UICollectionView setCollectionViewLayout:] + 318

在打印布局属性时,我看到一个布局属性项 layoutAttributesForItemAtIndexPath: length = 2, path = 0 - 0' ,我在布局中看到一个条目,所以不知道为什么找不到布局属性,

属性索引路径:( length = 2, path = 0 - 0);帧 = (6 293; 298 403.695);

属性索引路径:( length = 2, path = 0 - 1);帧 = (6 293; 298 408.695);

属性索引路径:( length = 2, path = 0 - 2);帧 = (6 293; 298 418.695);

属性索引路径:( length = 2, path = 0 - 3);帧 = (6 293;298 433.695);

属性索引路径:( length = 2, path = 0 - 4);帧 = (6 293; 298 453.695);

属性索引路径:( length = 2, path = 0 - 5);帧 = (6 293; 298 478.695);

属性索引路径:( length = 2, path = 0 - 6);帧 = (6 293; 298 508.695);

属性索引路径:( length = 2, path = 0 - 7);帧 = (6 293; 298 543.695);

属性索引路径:( length = 2, path = 0 - 8);帧 = (6 293; 298 583.695);

属性索引路径:( length = 2, path = 0 - 9);帧 = (6 293; 298 628.695);

属性索引路径:( length = 2, path = 0 - 10);帧 = (6 293; 298 678.695);

属性索引路径:( length = 2, path = 0 - 11);帧 = (6 293; 298 733.695);

属性索引路径:( length = 2, path = 0 - 12);帧 = (6 293; 298 793.695);

属性索引路径:( length = 2, path = 0 - 13);帧 = (6 293; 298 858.695);

属性索引路径:( length = 2, path = 0 - 14);帧 = (6 293; 298 928.695);

属性索引路径:( length = 2, path = 0 - 15);帧 = (6 293; 298 1003.69);

这就是我设置新的自定义布局的方式,

 self.collectionView!.collectionViewLayout = self.stackLayout
        self.stackLayout.delegate = self
        self.collectionView!.collectionViewLayout.invalidateLayout()
        self.collectionView!.setCollectionViewLayout(self.stackLayout,   animated:true)
        self.collectionView?.reloadData()

如果我静态加载两个自定义布局,它们可以正常工作,只有在动态更改布局时才会发生崩溃。

【问题讨论】:

尝试使用 startInteractiveTransitionToCollectionViewLayout 进行转换,同样的问题正在发生。 我也一样。我找不到这是来自哪里的代码。解释在哪里寻找以及如何修复会很棒。 【参考方案1】:

我有同样的问题,这解决了我的问题。

如果您使用多个自定义布局进行切换,则在两个自定义布局类中重写以下方法,

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

Swift 示例:

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? 
    return cache[indexPath.item]

目标 C 示例:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
 
   return self.cache[indexPath.item];

编码愉快..!

【讨论】:

以上是关于使用 setCollectionViewLayout 会导致崩溃,说 layoutAttributesForItemAtIndexPath not found的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)