同时移动和更新UITableViewCell和NSFetchedResultsController

Tyl*_*230 6 uitableview nsfetchedresultscontroller ios ios6

我有一个简单的表视图,包含1个部分和2个行.我正在使用a NSFetchedResultsController来保持表与CoreData同步.我对CD中的一行进行了更改,触发了一个要更新和移动的表视图单元格.问题是,当cellForRowAtIndexPath:在调用期间调用时NSFetchedResultsChangeUpdate,返回错误的单元格(这有意义b/c单元格尚未移动).因此,使用新更新的数据更新了错误的单元格.之后NSFetchedResultsChangeMove处理消息,以便单元格交换位置(单元格的内容都不会更新,因为它只是一个移动调用).结果是两个单元都反映了来自新更新的CD实体的数据.重新加载表可以解决问题.我正在运行iOS 6.换句话说,如果索引0处的单元格表示实体A而索引1表示实体B,并且我将实体A更新为A',使得2个单元格的顺序颠倒,结果就是我看到0:A'1:A,当我期望0:B,1:A'时.

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
//the wrong cell is updated here
            [self configureCell:(SyncCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
//this code produces errors too
            //[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            //[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

Tyl*_*230 6

解决方案是:

[self configureCell:(SyncCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:newIndexPath ? newIndexPath : indexPath];
Run Code Online (Sandbox Code Playgroud)

在更新期间提供新索引路径时使用新索引路径.然后使用delete和insert而不是move.我还是想知道是否有其他人有任何意见.


Toy*_*dor 5

我建议你看看这篇博文

修复错误很容易。只需依赖我上面描述的 UITableView 的行为,并将对 configureCell:atIndexPath: 的调用替换为 reloadRowsAtIndexPaths:withRowAnimation: 方法,它会自动做正确的事情:

case NSFetchedResultsChangeUpdate:
   [tableView reloadRowsAtIndexPaths:@[indexPath]  withRowAnimation:UITableViewRowAnimationAutomatic];
   break;
Run Code Online (Sandbox Code Playgroud)