UITableView动画在删除和插入高度不同的单元格时出现故障

UITableView动画在删除和插入高度不同的单元格时出现故障,uitableview,Uitableview,我对UITableView在同时删除和插入单元格时提供的动画有问题。 我有一个单元格列表,让我们问他们问题。点击一个问题时,应在其下方添加一个单元格,以显示该问题的答案。如果已显示另一个答案,则应从表中删除该答案。 当插入的单元格非常高时,会出现问题。如果它太高,以至于它的最终边界侵占了要删除的单元格所占据的空间,那么在动画中,我们可以通过要删除的回答单元格看到要添加的单元格 这就是我的代码在表视图中移动单元格时的样子 [tableView beginUpdates]; if (delete

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

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

[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];
但是,由于没有回调来确认表视图在启动第二个块之前完成了第一次集合更新,因此发生了几乎相同的问题。我知道我可以延迟使用执行选择器,但这看起来像绷带

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

[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后触发的,而不是在更新实际完成后触发的,所以这并不能解决使用问题

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


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

我通过隐藏控件解决了项目中的相同问题,如: 在~牢房里。我有

(void)setSelected:(BOOL)selected animated:(BOOL)animated;
{

if(selected == NO)
{
    self.selectedView.hidden = YES;
    self.descriptionLabel.hidden = YES;

}
else
{
    self.selectedView.hidden = NO;
    self.descriptionLabel.hidden = NO;

}
}

希望它仍然有用

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

tableView:didEndDisplayingCell:forRowAtIndexPath:
在此委托方法中插入新的答案行将生成正确的动画

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

endUpdates
在桌面视图上

[tableView beginUpdates];

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

[tableView endUpdates];

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

问题在于,当用户从屏幕中滚动该部分时,
tableView:didendisplayingcell:forRowAtIndexPath:
也会被触发