insertRowsAtIndexPaths:如果没有 reloadRowsAtIndexPaths,则不会设置动画:
insertRowsAtIndexPaths: doesn't animate without reloadRowsAtIndexPaths:
我创建了一组 类 来简化 table 视图的管理。他们所做的其中一件事是根据更新的数据为部分创建差异,然后应用正确的插入、删除和移动。
除了两个不合作的 table 视图外,这对我的大部分应用程序来说都很好用。称它们为 table A 和 table B。我找到了一个分别适用于每个问题的修复程序,但我无法同时修复它们。我检查过是否正确生成了差异,但出于某种原因,我在每个差异中得到了不同的动画。
table A 和 table B 都只是插入行。没有删除或移动。
在下面的代码中 BREAK_TABLE_A
导致:
- Table A - section=0 row>=1(不是 row=0)中的所有行移动到底部,同时从顶部重新设置动画。很丑
- Table B - 一个漂亮的插入动画
BREAK_TABLE_B
原因:
- Table A - 一个漂亮的插入动画
- Table B - 没有动画。就像
reloadData
最终,我实际上更喜欢 BREAK_TABLE_B 中的方法,因为这允许我为相同的数据保留相同的单元格,这意味着我可以使用 configureCell:.[=18 在这些单独的单元格上执行动画=]
代码比较简单:
UITableViewRowAnimation animation = UITableViewRowAnimationFade;
...
[self.tableView beginUpdates];
NSMutableSet *insertedPaths...;
NSMutableSet *deletedPaths...;
NSMutableSet *refreshPaths...; // Will contain any cell that was present before and after the update.
[self.tableView moveRowsAtIndexPaths:... // Not executed in these examples
...
[self.tableView insertRowsAtIndexPaths:insertedPaths.allObjects withRowAnimation:animation];
[self.tableView deleteRowsAtIndexPaths:deletedPaths.allObjects withRowAnimation:animation];
if (BREAK_TABLE_A){
[self.tableView reloadRowsAtIndexPaths:refreshPaths.allObjects withRowAnimation:UITableViewRowAnimationNone];
} else { //BREAK_TABLE_B - I would prefer this solution if possible
for (NSIndexPath *path in refreshPaths){
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
if (cell){
NSUInteger index = [newSection.rows indexOfObjectPassingTest:^BOOL(LQTableViewRow * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [obj.rowIdentifier isEqual:oldSection.rows[path.row].rowIdentifier];
}];
LQTableViewRow *row = newSection.rows[index];
[self configureCell:cell section:newSection row:row];
}
}
}
... update the actual data source ...
[self.tableView endUpdates];
为了解决这个问题,我尝试将上面的代码包装在 [CATransaction begin/commit/flush]
和 [UIView begin/commitAnimations]
块中。 CATransaction
在使用 table B 时,CATransaction
无错误地冻结了应用程序(可能在等待其他动画) B. UIView
导致两个视图(以及应用程序中的所有其他视图)动画不正确(单元格淡出)在他们的最终位置中从底部到顶部设置动画,而不是从 table 视图的顶部到底部)。
我还尝试用虚拟数据加载视图,使它们尽可能相似,并产生相同的奇怪结果。
好吧,原来是使用 CATransaction
时的崩溃让我找到了答案。我不小心在我的一个单元格中做了两次 [CATransaction begin]
,而不是提交事务。修复动画。
我创建了一组 类 来简化 table 视图的管理。他们所做的其中一件事是根据更新的数据为部分创建差异,然后应用正确的插入、删除和移动。
除了两个不合作的 table 视图外,这对我的大部分应用程序来说都很好用。称它们为 table A 和 table B。我找到了一个分别适用于每个问题的修复程序,但我无法同时修复它们。我检查过是否正确生成了差异,但出于某种原因,我在每个差异中得到了不同的动画。
table A 和 table B 都只是插入行。没有删除或移动。
在下面的代码中 BREAK_TABLE_A
导致:
- Table A - section=0 row>=1(不是 row=0)中的所有行移动到底部,同时从顶部重新设置动画。很丑
- Table B - 一个漂亮的插入动画
BREAK_TABLE_B
原因:
- Table A - 一个漂亮的插入动画
- Table B - 没有动画。就像
reloadData
最终,我实际上更喜欢 BREAK_TABLE_B 中的方法,因为这允许我为相同的数据保留相同的单元格,这意味着我可以使用 configureCell:.[=18 在这些单独的单元格上执行动画=]
代码比较简单:
UITableViewRowAnimation animation = UITableViewRowAnimationFade;
...
[self.tableView beginUpdates];
NSMutableSet *insertedPaths...;
NSMutableSet *deletedPaths...;
NSMutableSet *refreshPaths...; // Will contain any cell that was present before and after the update.
[self.tableView moveRowsAtIndexPaths:... // Not executed in these examples
...
[self.tableView insertRowsAtIndexPaths:insertedPaths.allObjects withRowAnimation:animation];
[self.tableView deleteRowsAtIndexPaths:deletedPaths.allObjects withRowAnimation:animation];
if (BREAK_TABLE_A){
[self.tableView reloadRowsAtIndexPaths:refreshPaths.allObjects withRowAnimation:UITableViewRowAnimationNone];
} else { //BREAK_TABLE_B - I would prefer this solution if possible
for (NSIndexPath *path in refreshPaths){
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:path];
if (cell){
NSUInteger index = [newSection.rows indexOfObjectPassingTest:^BOOL(LQTableViewRow * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [obj.rowIdentifier isEqual:oldSection.rows[path.row].rowIdentifier];
}];
LQTableViewRow *row = newSection.rows[index];
[self configureCell:cell section:newSection row:row];
}
}
}
... update the actual data source ...
[self.tableView endUpdates];
为了解决这个问题,我尝试将上面的代码包装在 [CATransaction begin/commit/flush]
和 [UIView begin/commitAnimations]
块中。 CATransaction
在使用 table B 时,CATransaction
无错误地冻结了应用程序(可能在等待其他动画) B. UIView
导致两个视图(以及应用程序中的所有其他视图)动画不正确(单元格淡出)在他们的最终位置中从底部到顶部设置动画,而不是从 table 视图的顶部到底部)。
我还尝试用虚拟数据加载视图,使它们尽可能相似,并产生相同的奇怪结果。
好吧,原来是使用 CATransaction
时的崩溃让我找到了答案。我不小心在我的一个单元格中做了两次 [CATransaction begin]
,而不是提交事务。修复动画。