ios – UITableView重新加载并在同一批次更新结果中移动行“尝试为单元格创建两个动画”

这是一个简单的例子(基本上由“Master-Detail”
Xcode模板制作).

我正在尝试移动一行(“B”)并在UITableView中的批量更新中重新加载另一行(“A1” – >“A2”).

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.objects = @[@"B", @"A1"];
}

- (IBAction)boom
{
    self.objects = @[@"A2", @"B"];

    NSIndexPath *path0 = [NSIndexPath indexPathForRow:0 inSection:0];
    NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0];

    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths:@[path1] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView moveRowAtIndexPath:path0 toIndexPath:path1];
    [self.tableView endUpdates];
}

这导致以下异常:

2015-01-14 17:58:51.290 batchtest[34004:806671] *** Assertion failure in -[_UITableViewUpdateSupport _setupAnimationsForNewlyInsertedCells], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableViewSupport.m:1216
2015-01-14 17:58:51.335 batchtest[34004:806671] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to create two animations for cell'
*** First throw call stack:
(
    0   CoreFoundation                      0x00946946 __exceptionPreprocess + 182
    1   libobjc.A.dylib                     0x005cfa97 objc_exception_throw + 44
    2   CoreFoundation                      0x009467da +[NSException raise:format:arguments:] + 138
    3   Foundation                          0x00243810 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118
    4   UIKit                               0x010b18e5 -[_UITableViewUpdateSupport(Private) _setupAnimationsForNewlyInsertedCells] + 8447
    5   UIKit                               0x010bb422 -[_UITableViewUpdateSupport _setupAnimations] + 207
    6   UIKit                               0x00df8bc1 -[UITableView _updateWithItems:updateSupport:] + 2089
    7   UIKit                               0x00df24a8 -[UITableView _endCellAnimationsWithContext:] + 13867
    8   UIKit                               0x00e07b6f -[UITableView endUpdatesWithContext:] + 51
    9   UIKit                               0x00e07b9d -[UITableView endUpdates] + 41

当我尝试将@ [path0]传递给reloadRowsAtIndexPaths而不是@ [path1]时,会发生同样的事情.

对我来说这看起来像是一个iOS错误.有办法解决吗?难道我做错了什么?

最佳答案 从我的角度来看,这个例外没有任何问题. reloadRowsAtIndexPaths:withRowAnimation:为正在重新加载的行创建动画,moveRowAtIndexPath:toIndexPath:也创建动画.显然,UITableView无法同时处理2个动画并引发异常.

我想将UITableViewRowAnimationNone传递给reloadRowsAtIndexPaths:withRowAnimation:可以解决问题但不确定;仍然值得尝试.

我建议这样的解决方法:

[self.tableView moveRowAtIndexPath:path0 toIndexPath:path1];
dispatch_async(dispatch_get_main_queue(), ^{
    self.objects = @[@"A2", @"B"];
    [self.tableView reloadRowsAtIndexPaths:@[path1]
                          withRowAnimation:UITableViewRowAnimationAutomatic];
});

或这个:

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    self.objects = @[@"A2", @"B"];
    [self.tableView reloadRowsAtIndexPaths:@[path1]
                          withRowAnimation:UITableViewRowAnimationAutomatic];
}];
[self.tableView moveRowAtIndexPath:path0 toIndexPath:path1];
[CATransaction commit];

或这个:

[UIView animateWithDuration:0.2 animations:^{
    [self.tableView moveRowAtIndexPath:path0 toIndexPath:path1];
} completion:^(BOOL finished){
    self.objects = @[@"A2", @"B"];
    [self.tableView reloadRowsAtIndexPaths:@[path1]
                          withRowAnimation:UITableViewRowAnimationAutomatic];
}];
点赞