在我的 UICollectionView
中,我使用一个简单的自定义对象数组来生成和显示单元格。偶尔,数据会发生变化,我想一次为所有变化制作动画。我选择通过跟踪第二个数组中的所有更改、比较两者并在 performBatchUpdates
block 内生成一组移动、插入、删除和更新操作来执行此操作。我现在意识到在同一个 block 中执行所有这些操作非常棘手,因为您必须担心索引的操作顺序。事实上,this issue 的公认答案是错误的(但在评论中更正)。
文档似乎很缺乏,但它涵盖了一种情况:
Deletes are processed before inserts in batch operations. This means the indexes for the deletions are processed relative to the indexes of the collection view’s state before the batch operation, and the indexes for the insertions are processed relative to the indexes of the state after all the deletions in the batch operation.
但是,该文档并未提及何时处理移动。如果我在同一 performBatchUpdates
中调用 moveItemAtIndexPath
和 deleteItemsAtIndexPaths
,移动索引应该与删除前或删除后的顺序相关吗? insertItemsAtIndexPaths
怎么样?
最后,我在同一操作中调用 reloadItemsAtIndexPaths
和 moveItemAtIndexPath
时遇到问题:
Fatal Exception: NSInternalInconsistencyException attempt to delete and reload the same index path
有没有办法在同一个 performBatchUpdates
中完成我想要的所有操作?如果是这样,更新相对于其他更新的处理顺序是什么?如果不是,人们通常做什么?在完成所有其他操作后重新加载数据?前?如果所有动画都发生在一个阶段,我会更喜欢。
最佳答案
Mark's answer是正确的。我建议观看 WWDC's 2018 Session 225 "A Tour of UICollectionView"从 Apple 工程师那里获得完整的解释。
您可以 skip to the 33'36" mark有趣的一点。
视频摘要
- 2 个列表:“原始项目”(任何更改前)和“最终项目”(所有更改后);
- 原始索引→原始项目中的索引
- Final indexes → final items 中的索引
PerformBatchUpdates
中的操作顺序
- 删除 → 始终使用原始索引(将按降序使用)
- 插入 → 始终使用最终索引(将按升序使用)
- 移动 → 从 = 原始索引; To=最终索引
- 重新加载 → 在引擎盖下,它删除然后插入。索引 = 原始索引。您无法重新加载已移动的项目。
要重新加载移动的项目,请在单独的 PerformBatchUpdates
中调用所有重新加载,在 PerformWithoutAnimation
中(因为重新加载从不动画)。
关于ios - 如何在 UICollectionView performBatchUpdates block 中对移动、插入、删除和更新进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38597804/