Как я могу удалить строку из UITableView сразу после добавления? - PullRequest
0 голосов
/ 18 января 2012

Я добавил к своему UITableView следующий метод, чтобы предоставить пользователю возможность удалить строку:

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

Я скопировал этот метод из шаблона XCode с параметром

Использовать CoreData для хранилища

Как только пользователь нажимает addButton в UITableView, открывается новый UIView, где он должен ввести информацию для новой сущности.

Затем пользователь касается saveButton в UIView. Информация читается и сохраняется в контексте. UIView закрыт, и пользователь вернется к UITableView.

Новая запись теперь появляется в новой строке. Если пользователь теперь понимает, что совершил ошибку и хочет немедленно удалить эту строку (стереть слева направо, а затем нажать «Удалить»), строка остается, и больше ничего не происходит. Мне выдаётся следующая ошибка:

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)

Но удаление строки работает, если я выйду из приложения до того, как произойдет удаление. (и заново просмотреть, а затем удалить)

В controllerDidChangecontent вызывается только [self.tableView endUpdate].

Мой метод выглядит так:

- (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();
        }
    }   
}

Я думаю, что строка была добавлена, но не зафиксирована. И тогда он попытается удалить строку, о которой он не знает. Я правильно понимаю? Но я не знаю точно, где исправить ошибку. Что я могу сделать? Кто-нибудь знает?

1 Ответ

2 голосов
/ 18 января 2012

Посмотрите на сообщение об ошибке: также необходимо удалить строку из табличного представления .

Если вы используете NSFetchedResultsController, вы можете сделать это следующим образом:

// in controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
case NSFetchedResultsChangeDelete:
   [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
                    withRowAnimation:UITableViewRowAnimationFade];
break;

Также обратите внимание, что ваш fetchedResultsController должен быть проинформирован о том, что он должен повторно получить новый набор результатов - в противном случае tableView:numberOfRowsInSection вернет старое значение. Так что вам нужно вставить:

self.fetchedResultsController = nil;

Он будет лениво воссоздавать себя с правильными разделами и строками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...