删除和插入具有不同高度的单元格时 UITableView 动画故障 [英] UITableView animation glitch when deleting and inserting cells with varying heights

查看:26
本文介绍了删除和插入具有不同高度的单元格时 UITableView 动画故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having a problem with the animation that UITableView provides when deleting and inserting a cell at the same time. I have a list of cells lets call them questions. When one question is tapped it should add a cell beneath itself to display the answer to that question. If another answer is already being displayed that answer should be removed from the table. The issue arises when the cell being inserted is very tall. If it is so tall that it's eventual bounds encroach into the space that the cell to be deleted takes up then during the animation we see the through the answer cell that we are deleting to see the cell that is being added

(见问题视频链接)

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

the is what my code looks like to move around the cells in the table view

[tableView beginUpdates];

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

[tableView endUpdates];

我试过了

[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];

但是因为没有回调确认表视图在开始第二个块之前完成了第一个集合更新,所以发生了几乎相同的问题.我知道我可以使用带有延迟的执行选择器,但这似乎是一个创可贴.

But because there's no callback confirming that the table view did complete the first set update before starting the second block pretty much the same problem occurs. I know I could use perform selector with delay, but this seems like a bandaid.

第二次我尝试将动画包含在这样的块中

Second I tried to encompass the animation in a block like this

[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];
}];

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

Again, because the completion block is fired after we call endUpdates not after the updates actually complete this does not resolve the use.

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

I also went into storyboard to be sure that clip subviews to bounds is selected for the cells. Again, this does not resolve the issue because we are not seeing a subview of the cell expand beyond it's expected height.

通过放慢动画来仔细观察动画,看起来苹果将要添加的单元格插入到表格中不会更改的单元格下,然后将将保留的单元格移动到新位置.结果,被删除的单元格变成了一个透明的窗口,在那里我们可以看到他们在幕后实际做了什么.

Looking closer at the animation by slowing it down it looks like apple inserts the cell to be added under the cells that won't be changed in the table and then moves the cells that will remain into their new positions. As a result the cell that was deleted becomes a transparent window where we see what they are actually doing under the hood.

推荐答案

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

The right approach would be to first remove the old answer and then after the animation is over add the new answer. There is a UITableViewDelegate method that is triggered after the cell animation is complete.

tableView:didEndDisplayingCell:forRowAtIndexPath:

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

Inserting the new answer row within this delegate method will result in the correct animation.

需要记住一些细节 - 您需要一些逻辑来确保返回正确的单元格高度并返回该部分中正确的预期行数.在我们删除旧答案后调用这些数据源方法,并在调用

There are a few details to keep in mind- You'll need some logic to ensure that the correct cell height is returned and that the correct number of expected rows in the section is returned. Those data source methods are called after we remove our old answer in and again when we add the new one when we call

endUpdates

在表格视图上

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

Using anything other than UITableViewRowAnimationTop results in some strange animation behavior. This is because the content view of the cell is not what is being animated.

这篇关于删除和插入具有不同高度的单元格时 UITableView 动画故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆