6

我在同时删除和插入单元格时遇到 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 之后而不是在更新实际完成之后触发的,所以这并不能解决使用问题。

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

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

4

2 回答 2

2

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

tableView:didEndDisplayingCell:forRowAtIndexPath:

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

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

endUpdates

在表视图上

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

于 2013-06-14T00:58:58.170 回答
0

我通过隐藏控件解决了我的项目中的相同问题,例如:在 ~cell.m 中有

(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;

}
}

可能还有帮助吗

于 2013-04-05T13:18:44.703 回答