我已经创建了一组类来简化管理表视图。他们所做的一件事是根据更新的数据为部分创建差异,然后应用正确的插入,删除和移动。
除了两个不合作的表视图外,这对我的大多数应用程序都很有效。称他们为表A和表B.我找到了一个适用于每个人的修复程序,但我无法同时修复这两个修复程序。我检查过差异是否正确生成,但出于某种原因,我在每个动画中都有不同的动画。
表A和表B都只是插入行。没有删除或移动。
在下面的代码BREAK_TABLE_A
中导致:
BREAK_TABLE_B
原因:
reloadData
最终,我实际上更喜欢BREAK_TABLE_B中的方法,因为这允许我为相同的数据保留相同的单元格,这意味着我可以使用configureCell在这些单独的单元格上执行动画:。
代码相对简单:
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
在使用表B时没有错误(可能正在等待其他一些动画)冻结应用程序。UIView
导致两个视图(以及应用程序中的所有其他视图)不正确地设置动画(单元格淡入和动画来自从他们的最终位置的底部到顶部,而不是从桌面的顶部到底部)。
我还尝试使用虚拟数据加载视图,以使它们尽可能相似,但结果相同。
答案 0 :(得分:0)
嗯,事实证明使用CATransaction
时的崩溃导致了我的答案。我不小心在我的一个单元格中执行了[CATransaction begin]
两次,而不是提交事务。修复修复动画。