【问题标题】:How to order moves, inserts, deletes, and updates in a UICollectionView performBatchUpdates block?如何在 UICollectionView performBatchUpdates 块中对移动、插入、删除和更新进行排序?
【发布时间】:2016-11-30 13:40:08
【问题描述】:

在我的UICollectionView 中,我使用一个简单的自定义对象数组来生成和显示单元格。有时数据会发生变化,我想一次性为这些变化设置动画。我选择通过跟踪第二个数组中的所有更改,区分两者,并在performBatchUpdates 块内生成一组移动、插入、删除和更新操作来做到这一点。我现在意识到在同一个块中执行所有这些操作非常棘手,因为您必须担心索引操作的顺序。事实上,this issue 的公认答案是错误的(但在 cmets 中已更正)。

文档似乎很缺乏,但它涵盖了一种情况:

在批处理操作中,在插入之前处理删除。这意味着 删除的索引是相对于 批处理操作之前集合视图的状态,以及 插入的索引相对于 批处理操作中所有删除后的状态。

但是,文档没有说明何时处理移动。如果我在同一个performBatchUpdates 中调用moveItemAtIndexPathdeleteItemsAtIndexPaths,移动索引应该相对于删除前还是删除后的顺序? insertItemsAtIndexPaths呢?

最后,我在同一操作中调用reloadItemsAtIndexPathsmoveItemAtIndexPath 时遇到问题:

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

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

【问题讨论】:

    标签: ios objective-c swift uicollectionview uikit


    【解决方案1】:

    Mark's answer 是对的。我建议您观看 WWDC's 2018 Session 225 "A Tour of UICollectionView" 以获得 Apple 工程师的完整解释。

    您可以skip to the 33'36" mark 获取有趣的信息。

    视频摘要

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

    PerformBatchUpdates中的操作顺序

    1. 删除 → 始终使用原始索引(将按降序使用)
    2. 插入 → 始终使用最终索引(将按升序使用)
    3. 移动 → 从 = 原始索引; To = 最终索引
    4. 重新加载 → 在后台,它先删除然后插入。索引 = 原始索引。您无法重新加载已移动的项目。

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

    【讨论】:

      【解决方案2】:

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

      验证操作设置是否正确的简便方法:重新加载、插入和移动到 indexPath 的集合不应有任何重复,而重新加载、删除和移动的 indexPath 集合不应有任何重复.

      更新:

      您移动的项目似乎也没有更新,而只是移动了。因此,如果您需要更新和移动项目,您可以在批量更新之前或之后执行重新加载(取决于数据源的状态)。

      【讨论】:

      • 假设我有一个需要更新的单元格,因为它会以不同的方式显示(例如不同的颜色),而且我还需要移动它。这是我需要移动和重新加载的示例。有没有办法在同一个动画块中做到这些?
      • 因为您正在移动,单元格将自动重新加载。你不需要显式地重新加载它。
      • 哦!我没有意识到(我想我没有尝试这个案例)。我以为它只会移动内容容器而不重新加载它们。
      • 是在插入之前还是之后移动?还是就索引而言,移动与删除加插入相同?
      • 后者。要找出你的移动索引,假设它是一个删除和一个插入。
      猜你喜欢
      • 1970-01-01
      • 2012-09-21
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多