Deleting table row with animation using core data

2019-08-14 09:02发布

问题:

If I delete a row from my table using a standard animation such as UITableViewRowAnimationFade the code crashes with this error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (4) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'

If I remove the animation line the row removal/deletion works, but I no longer have the cool Apple delete transition.

Here is my code - any help is appreciated. This method of deleting rows worked prior to iOS4, not sure if something has changed?

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
        MyItem *myItem = [self.getItemsFetchedResultsController objectAtIndexPath:path];
        [dataRepository deleteItem:myItem];

        // If I comment this line out the delete works but I no longer have the animation
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

        [self.tableView reloadData];

    }

}

Data Repository:

-(void)deleteItem:(MyItem *)myItem {
    [self.managedObjectContext deleteObject:myItem];
    [self saveCurrentContext];
}

回答1:

I resolved this issue by using this code before and after the table update:

[tableView beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete) {
    ... 
}
[tableView endUpdates];


回答2:

One reason for this could be if you have set NSFetchedResultsControllerDelegate and implemented controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: It will be called when you save the context and update the table view on your behalf. You might have code like this:

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

Generally when you get the error it means that you have not updated the data source in the way you specified with deleteRowsAtIndexPaths:withRowAnimation:. When you call that method you guarantee that you have already updated the data source to reflect that change.