使用自定义布局重新加载 UICollectionView 会引发错误

Posted

技术标签:

【中文标题】使用自定义布局重新加载 UICollectionView 会引发错误【英文标题】:Reloading UICollectionView with custom layout throws error 【发布时间】:2017-05-31 07:37:39 【问题描述】:

我正在尝试使用 tutorial 在我的 UICollectionView 上实现 Apple Watch 动画。 它有一个单独的 UICollectionViewLayout 类用​​于所需的布局。

我把我的元素放在数组中,当我必须用我以前调用的新值更新集合视图时

self.collectionView.reloadData()

但它让我跟随错误

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3600.8.1/UICollectionViewData.m:433

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0x170222520> length = 2, path = 0 - 1'

然后我用了

self.collectionView.collectionViewLayout.invalidateLayout()

在重新加载之前使布局无效。但是我的代码仍然抛出以前的错误。所以我尝试重新加载部分:

let indexSet = IndexSet(integer: 0)
self.collectionView.reloadSections(indexSet)

这一次有时布局显示不正确。它有一个扭曲的 UI,有时它会在以下代码行中引发 EXC_BAD_ACCESS 错误:

 self.collectionView.collectionViewLayout = layout // error comes on this line

有什么解决办法吗?请查看上面提到的教程以了解我的代码。我参考了很多答案,但我无法解决这个问题。

【问题讨论】:

【参考方案1】:

问题是因为即使数据为 nil,您也会返回 UICollectionViewLayoutAttributes,因此出现错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0x170222520> length = 2, path = 0 - 1'

在tutorial 中,返回属性的方法layoutAttributesForItemAtIndexPath 是从layoutAttributesForElementsInRect 调用的,其中cellCountcellCount = ROWS * COLS

假设您可能已更改 numberOfItemsInSection 以反映您的数据,您也必须更改 cellCount 的条件。

【讨论】:

随着数组中数据的更新,单元格数可能会发生变化,也可能不会发生变化。 @Sabah 我的意思是,cellCount 没有在这里更新(除非你正在这样做) for i in 0 .. Abdul 单元格计数的条件已相应更改,layoutAttributesForItemAtIndexPath 正在返回单元格的布局。在return attributes这一行在layoutAttributesForElements执行之后,错误来了 嗯,我的错。也许您可以尝试在viewWillLayoutSubviews 中使用invalidateLayout 子类化您的UICollectionView 和无效布局 Abdul 问题似乎与 cellCount 有关,但与您的预期略有不同。谢谢你的帮助。它导致正确的方向

以上是关于使用自定义布局重新加载 UICollectionView 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章