删除和插入具有不同高度的单元格时UITableView动画故障

Nat*_*ten 6 uitableview

我在UITableView同时删除和插入单元格时提供的动画有问题.我有一个单元格列表让我们称他们为问题.当点击一个问题时,它应在其下方添加一个单元格以显示该问题的答案.如果已经显示另一个答案,则应从表中删除答案.当插入的细胞非常高时会出现问题.如果它太高以至于最终边界会侵入要删除的单元格占用的空间,那么在动画期间我们会看到通过我们正在删除的应答单元格以查看正在添加的单元格

(参见问题视频的链接)

这是我的代码在表视图中移动单元格的样子

[tableView beginUpdates];

if (deleteIndex) {
    [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
if (addIndex) {
[tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}

[tableView endUpdates];
Run Code Online (Sandbox Code Playgroud)

我试过了

[tableView beginUpdates];

if (deleteIndex) {
    [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
}
[tableView endUpdates];

//do stuff to update data source

[tableView beginUpdates];

if (addIndex) {
[tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
}

[tableView endUpdates];
Run Code Online (Sandbox Code Playgroud)

但是因为在启动第二个块之前没有回调确认表视图确实完成了第一个集更新,所以几乎出现了同样的问题.我知道我可以使用延迟执行选择器,但这似乎是一个绑带.

其次,我试图在这样的块中包含动画

[UIView animateWithDuration:0.0 animations:^{
    [tableView beginUpdates];

    if (deleteIndex) {
        [tableView deleteRowsAtIndexPaths:@[deleteIndex] withRowAnimation:UITableViewRowAnimationTop];
    }
    [tableView endUpdates];

    //do stuff to update data source

} completion:^(BOOL finished) {

    [tableView beginUpdates];

    if (addIndex) {
        [tableView insertRowsAtIndexPaths:@[addIndex] withRowAnimation:UITableViewRowAnimationTop];
    }

    [tableView endUpdates];
}];
Run Code Online (Sandbox Code Playgroud)

同样,因为在我们调用endUpdates之后没有在更新实际完成之后触发完成块,这不会解决使用问题.

我还进入了故事板,以确保为单元格选择剪辑子视图到边界.同样,这并不能解决问题,因为我们没有看到单元格的子视图超出预期的高度.

通过减慢它的速度来仔细观察动画,看起来苹果将要添加的单元格插入到表格中不会更改的单元格下,然后移动将保留在新位置的单元格.结果,删除的单元格变成了一个透明窗口,我们可以看到它们在引擎盖下实际执行的操作.

Nat*_*ten 2

正确的方法是首先删除旧答案,然后在动画结束后添加新答案。有一个 UITableViewDelegate 方法,在单元格动画完成后触发。

tableView:didEndDisplayingCell:forRowAtIndexPath:
Run Code Online (Sandbox Code Playgroud)

在此委托方法中插入新的答案行将产生正确的动画。

有一些细节需要记住 - 您需要一些逻辑来确保返回正确的单元格高度以及返回该部分中正确的预期行数。这些数据源方法在我们删除旧答案后被调用,当我们调用时添加新答案时会再次调用

endUpdates
Run Code Online (Sandbox Code Playgroud)

在表视图上

使用 UITableViewRowAnimationTop 以外的任何内容都会导致一些奇怪的动画行为。这是因为单元格的内容视图不是正在动画化的内容。