iOS 10的bug:UICollectionView收到一个索引path不存在的单元格的布局属性
在iOS 10的设备上运行我的应用程序我得到这个错误:
UICollectionView收到一个索引path不存在的单元格的布局属性
在iOS 8和9工作正常。 我一直在研究,我发现这是相关的无效的集合视图布局。 我试图实现这个解决scheme没有成功,所以我想要求直接的帮助。 这是我的层次结构视图:
->Table view ->Each cell of table is a custom collection view [GitHub Repo][1] ->Each item of collection view has another collection view
我试过的是插入
[self.collectionView.collectionViewLayout invalidateLayout];
在里面
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
的收集意见。
此外,我已经尝试在做一个重载数据之前使布局无效,不起作用…
任何人都可以给我一些方向吗?
collectionView中的单元格数量发生变化时,发生了这种情况。 原来我在调用reloadData之后丢失了invalidateLayout。 join后,我没有再遇到任何崩溃。 Apple在iOS10中对collectionView进行了一些修改。 我想这就是为什么我们没有遇到旧版本相同的问题。
这是我的最终代码:
[self.collectionView reloadData]; [self.collectionView.collectionViewLayout invalidateLayout];
我也在同一视图中遇到了2个collectionView,因为我在两个集合中添加了相同的UICollectionViewFlowLayout:
let layout = UICollectionViewFlowLayout() collectionView1.collectionViewLayout = layout collectionView2.collectionViewLayout = layout
当然,如果collectionView1数据发生变化,它会在重载数据上崩溃。 如果这可以帮助某人。
以前的答案有帮助,但如果您使用自动调整单元格,则其大小将不正确。
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.estimatedItemSize = CGSizeMake(60, 25); layout.itemSize = UICollectionViewFlowLayoutAutomaticSize; self.collectionView.collectionViewLayout = layout;
我通过replace来解决这个问题
[self.collectionView reloadData];
至
[self.collectionView reloadSections:indexSet];
当你有自定义的布局,记得清除caching(UICollectionViewLayoutAttributes),而重写准备func
override func prepare() { cache.removeAll()
每次都不是最好的重载(你应该使用insertItems和deleteItems,甚至reloadSections)。 但是……在说过某些情况下这是有效的,你可以这样做:
collectionView.dataSource = nil collectionView.delegate = nil /*... All changes here. ... */ collectionView.dataSource = self collectionView.delegate = self collectionView.reloadData()
我也有这个问题。 在我的情况下,有一个自定义的UICollectionViewLayout
应用到集合视图&问题是,它有陈旧的数据应该显示的单元格的数量。 当你看到UICollectionView received layout attributes for a cell with an index path that does not exist
时,你肯定可以检查
@ Katrin的答案帮助了很多,但是我可以通过添加一行来获得更好的结果:
collectionView.reloadData() collectionView.collectionViewLayout.invalidateLayout() collectionView.layoutSubviews() // <-- here it is :)
现在我不能说是否可以用这条线来重现崩溃,但是我猜想有一个……所以,仍然不是一个银弹,而是一些东西。
如果你想保持你的滚动位置和修复崩溃,你可以使用这个:
collectionView.reloadData() let context = collectionView.collectionViewLayout.invalidationContext(forBoundsChange: collectionView.bounds) context.contentOffsetAdjustment = CGPoint.zero collectionView.collectionViewLayout.invalidateLayout(with: context)