如何在UICollectionView performBatchUpdates块中排序移动,插入,删除和更新?

Bre*_*aut 14 objective-c uikit ios uicollectionview swift

在我看来UICollectionView,我使用一个简单的自定义对象数组来生成和显示单元格.偶尔数据会发生变化,我想一次性对变化进行动画处理.我选择通过跟踪第二个数组中的所有更改,区分这两个更改,并在performBatchUpdates块内部生成一组移动,插入,删除和更新操作来完成此操作.我现在意识到在同一个块中执行所有这些操作非常棘手,因为您不得不担心索引操作的顺序.事实上,这个问题的公认答案是错误的(但在评论中已经纠正).

文档似乎很缺乏,但它涵盖了一个案例:

在批处理操作中插入之前处理删除.这意味着删除的索引相对于批处理操作之前的集合视图的状态的索引进行处理,并且在批处理操作中的所有删除之后,相对于状态的索引处理插入的索引.

但是,该文档没有讨论何时处理移动.如果我打电话moveItemAtIndexPath并且deleteItemsAtIndexPaths相同performBatchUpdates,移动索引是否应该相对于删除前或删除后的订单?怎么样insertItemsAtIndexPaths

最后,我面临着调用reloadItemsAtIndexPathsmoveItemAtIndexPath同一操作的问题:

致命异常:NSInternalInconsistencyException尝试删除并重新加载相同的索引路径

有没有办法在同一个地方做我想要的所有操作performBatchUpdates?如果是,那么更新相对于其他更新的处理顺序是什么?如果没有,人们通常会做什么?在完成所有其他操作后重新加载数据?之前?如果所有的动画都发生在一个阶段,我更喜欢.

Gui*_*gis 10

马克的答案是正确的。我建议您观看WWDC的2018年会议225“ UICollectionView之行”,以获取Apple工程师的完整解释。

您可以跳到33'36“标记以获得有趣的位置。

集合视图更新合并幻灯片

影片摘要

  • 2个列表:“原始项目”(任何更改之前)和“最终项目”(所有更改之后);
  • 原始索引?原始项目中的索引
  • 最终指标?最终项目中的索引

操作顺序 PerformBatchUpdates

  1. 删除?始终使用原始索引(降序使用)
  2. 插入?始终使用最终索引(将以升序使用)
  3. 动作?发件人=原始索引;至=最终索引
  4. 重新加载?在引擎盖下,它删除然后插入。索引=原始索引。您无法重新加载已移动的项目。

要重新加载已移动的项目,请在单独的PerformBatchUpdates内调用所有重新加载PerformWithoutAnimation(因为重新加载从不动画)。


Mar*_*ark 8

对于移动操作,from indexPath是预删除索引,to indexPath是删除后索引.仅应为尚未插入,删除或移动的indexPath指定重新加载.这可能就是你看到的原因NSInternalInconsistencyException.

验证操作的一种方便的方法是正确设置的:重新加载,插入和移动到索引路径的集合不应该有任何重复,并且重新加载,删除和移动索引路径集不应该有任何重复.

更新:

看来您移动的项目也不会更新,但只会移动.因此,如果需要更新和移动项目,可以在批量更新之前或之后执行重新加载(取决于数据源的状态).