我遇到了UITableView在同时删除和插入单元格时提供的动画问题。 我有一个单元格列表让我们称他们为问题。当点击一个问题时,它应在其下方添加一个单元格以显示该问题的答案。如果已经显示另一个答案,则应从表中删除答案。 当插入的细胞非常高时会出现问题。如果它太高以至于最终边界会侵入要删除的单元格所占据的空间,那么在动画期间我们会看到正在删除的应答单元格以查看正在添加的单元格
(see link to video of problem)
这是我的代码在表格视图中移动单元格的样子
[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之后没有在更新实际完成之后触发完成块,这不能解决使用问题。
我还进入了故事板,以确保为单元格选择剪辑子视图到边界。同样,这并不能解决问题,因为我们没有看到单元格的子视图超出预期的高度。
通过减慢速度来仔细观察动画,看起来苹果会将要添加的单元格插入到表格中不会更改的单元格中,然后移动将保留在新位置的单元格。结果,被删除的单元格变成了一个透明的窗口,我们可以看到它们实际上是在做什么。
答案 0 :(得分:2)
正确的方法是首先删除旧答案,然后在动画结束后添加新答案。在单元格动画完成后会触发一个UITableViewDelegate方法。
tableView:didEndDisplayingCell:forRowAtIndexPath:
在此委托方法中插入新的答案行将产生正确的动画。
需要记住一些细节 - 您需要一些逻辑来确保返回正确的单元格高度,并返回该部分中正确的预期行数。在我们删除旧答案之后调用这些数据源方法,并在我们调用
时添加新答案时再次调用endUpdates
表视图上的
使用除UITableViewRowAnimationTop以外的任何内容会导致一些奇怪的动画行为。这是因为单元格的内容视图不是动画的内容。
答案 1 :(得分: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;
}
}
可能仍然有帮助