I’ve added to my UITableView the following method to provide the user with the option to delete a line:
(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
I have copied this method from the XCode template with the option
Use CoreData for Storage
Once the user pushes the addButton in the UITableView a new UIView is opened where he should enter the information for a new entity.
Then the user touches the saveButton in the UIView. The information is read and stored in the context. The UIView is closed and the user will get back to UITableView.
The new entry now appears in a new row. If the user now realizes he has made a mistake and wants to delete this row immediately (wipe from left to right and then touch “Delete”) the row remains and nothing else happens. The following error is thrown to me:
An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.
Invalid update: invalid number of rows in section 0.
The number of rows contained in an existing section after the update (1)
must be equal to the number of rows contained in that section before the update (1),
plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).
with userInfo (null)
But deleting the row works if I exit the app before the deleting happens. (and re-viewed, and then delete)
In controllerDidChangecontent only [self.tableView endUpdate] is called.
My method looks like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object for the given index path
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
//NSLog(@"DATE: %@", [[UIApplication sharedApplication] scheduledLocalNotifications]);
for (UILocalNotification *notification in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
NSLog(@"N: %@", notification.fireDate);
NSLog(@"O: %@", [[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:@"zeit"]);
if (notification.fireDate == [[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:@"zeit"]) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
NSLog(@"GELÖSCHT!");
}
}
// Save the context.
NSError *error = nil;
if (![context save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
I think the row was added but not commited. And then it will attempt to delete a row that it does not know about. Do I understand this correctly?
But I do not know exactly where to fix the error.
What can I do? Does anybody know?
Look at the error message: you also have to delete the row from the table view.
If you are using an
NSFetchedResultsController, you can do it like this:Also notice that your
fetchedResultsControllerhas to be informed that it should re-fetch the a new result set – otherwisetableView:numberOfRowsInSectionwill return the old value. So you need to insert:It will recreate itself lazily with the correct sections and rows.