insertRowsAtIndexPaths:没有 reloadRowsAtIndexPaths 就不会动画:

Posted

技术标签:

【中文标题】insertRowsAtIndexPaths:没有 reloadRowsAtIndexPaths 就不会动画:【英文标题】:insertRowsAtIndexPaths: doesn't animate without reloadRowsAtIndexPaths: 【发布时间】:2016-06-29 04:51:45 【问题描述】:

我创建了一组类来简化表视图的管理。他们所做的其中一件事是根据更新的数据为部分创建差异,然后应用正确的插入、删除和移动。

这对我的大多数应用程序都很好,除了两个不合作的表格视图。称它们为表 A 和表 B。我找到了一个适用于每个单独的修复程序,但我不能同时修复两者。我检查了差异是否正确生成,但由于某种原因,我得到了不同的动画。

表 A 和表 B 都只是插入行。没有删除或移动。

在下面的代码中BREAK_TABLE_A 原因:

表 A - 部分中的所有行=0 行>=1(不是行=0)移动到底部,同时从顶部重新设置动画。很丑 表 B - 一个不错的插入动画

BREAK_TABLE_B 原因:

表 A - 一个不错的插入动画 表 B - 无动画。就像reloadData

最终,我实际上更喜欢 BREAK_TABLE_B 中的方法,因为这允许我为相同的数据保留相同的单元格,这意味着我可以使用 configureCell 对这些单独的单元格执行动画:。

代码比较简单:

  UITableViewRowAnimation animation = UITableViewRowAnimationFade;
    ...
    [self.tableView beginUpdates];

    NSMutableSet *insertedPaths...;
    NSMutableSet *deletedPaths...;
    NSMutableSet *refreshPaths...; // Will contain any cell that was present before and after the update.

    [self.tableView moveRowsAtIndexPaths:... // Not executed in these examples
    ...
    [self.tableView insertRowsAtIndexPaths:insertedPaths.allObjects withRowAnimation:animation];
    [self.tableView deleteRowsAtIndexPaths:deletedPaths.allObjects withRowAnimation:animation];

    if (BREAK_TABLE_A)
        [self.tableView reloadRowsAtIndexPaths:refreshPaths.allObjects withRowAnimation:UITableViewRowAnimationNone];
     else  //BREAK_TABLE_B - I would prefer this solution if possible
        for (NSIndexPath *path in refreshPaths)
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
            if (cell)
                NSUInteger index = [newSection.rows indexOfObjectPassingTest:^BOOL(LQTableViewRow * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) 
                    return [obj.rowIdentifier     isEqual:oldSection.rows[path.row].rowIdentifier];
                ];
                LQTableViewRow *row = newSection.rows[index];
                [self configureCell:cell section:newSection row:row];
            
        
    

    ... update the actual data source ...
    [self.tableView endUpdates];

为了解决这个问题,我尝试将上述代码包装在 [CATransaction begin/commit/flush][UIView begin/commitAnimations] 块中。 CATransaction 在使用表 B 时冻结应用程序而没有错误(可能正在等待一些其他动画)。UIView 导致两个视图(以及应用程序中的所有其他视图)的动画不正确(单元格淡入并从底部到顶部动画它们的最终位置,而不是从 tableview 的顶部到底部)。

我还尝试使用虚拟数据加载视图,以使它们彼此尽可能相似,并产生相同的奇怪结果。

【问题讨论】:

【参考方案1】:

好吧,事实证明,使用CATransaction 时的崩溃让我找到了答案。我不小心在我的一个单元格中做了两次[CATransaction begin],而不是提交事务。修复动画。

【讨论】:

以上是关于insertRowsAtIndexPaths:没有 reloadRowsAtIndexPaths 就不会动画:的主要内容,如果未能解决你的问题,请参考以下文章

控制 uitableview insertRowsAtIndexPath 动画的速度

insertRowsAtIndexPaths 为每一行调用 cellForRowAtIndexPath

insertRowsAtIndexPaths 自定义动画 Swift

带有 2 个动画的 insertRowsAtIndexPaths

insertRowsAtIndexPaths: with scrollToRowAtIndexPath: 导致 UITableView 部分被错误地隐藏

如何使用 insertRowsAtIndexPaths 将数组内的字典添加到 UItableview?