invalidateLayout() 和 reloadData() 之间的区别

Posted

技术标签:

【中文标题】invalidateLayout() 和 reloadData() 之间的区别【英文标题】:Difference between invalidateLayout() and reloadData() 【发布时间】:2020-08-26 05:48:20 【问题描述】:

我想知道invalidateLayout()reloadData() 之间有什么区别 我已阅读文档here 和here,但留下以下问题:

    我有数据作为数组,这样cellForItemAt indexPath 可以直接用dataArray[indexPath.item] 引用数组,并且数组中的每个数据对象都可以填充单元格。 reloadData() 将确保在对dataArray 进行更改时,这会反映在collectionView 中。通过一些小测试,invalidateLayout() 似乎也会观察到这种变化。总是这样吗? 这两个函数在调整单元格大小方面似乎具有相同的效果,这总是正确的吗? 当调用invalidateLayout() 时,是否也会像reloadData() 一样为每个单元格调用cellForItemAt indexPath? 如果以上所有情况都成立,那么您是否还需要使用 reloadData(),因为 Apple 表示要谨慎使用它?

任何其他关于这两个函数在基本层面上的差异的 cmet 都会有所帮助(何时使用每个函数等)

【问题讨论】:

当您想要更新单元格的内容时,您应该始终使用 reloadData。 invalidateLayout() 不会触发 cellForItem (至少它不能保证),它会更新大小和布局。更新布局(如旋转设备) - invalidateLayout, data - reloadData 【参考方案1】:

经过进一步测试...

    cellForItemAt indexPath 将仅对不在屏幕上但由于invalidateLayout() 而现在在屏幕上的单元格调用。 这似乎是真的 请参阅问题 1 的答案。如果您移动了单元格并且每个单元格中的数据与数据源的顺序不同,这可能会导致问题。 我现在使用reloadData() 的次数少了很多

一般来说,reloadData() 看起来也调用了invalidateLayout()(或者至少有类似的效果)并且会为每个单元格触发cellForItemAt indexPath。但是,invalidateLayout() 只会在单元格现在位于屏幕边界内并且由于布局更改而需要重新加载时才会调用 cellForItemAt indexdPath

【讨论】:

谢谢你亲爱的先生?当我们一群 SO-ers 花费数小时弄清楚基本的东西时,为什么苹果甚至需要正确记录这些东西。

以上是关于invalidateLayout() 和 reloadData() 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

使用 invalidateLayout 调用的高级 UICollectionView 动画

iOS8 中的 invalidateLayout 等效项

使用 invalidateLayout 加载数据后调整 UICollectionViewCell 的大小

UICollectionView invalidateLayout 不会在屏幕方向更改时触发 sizeForItem

动画 UICollectionView contentInset 调整

通过捏合手势缩放 UICollectionView