Документы для NSFetchedResultsControllerDelegate предоставляют следующий пример кода.
- (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:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Когда я создаю новый NSManagedObject, срабатывает NSFetchedResultsChangeInsert (отлично!). Когда я изменяю значение атрибута (используемого для заголовка ячейки), срабатывает NSFetchedResultsChangeUpdate. К сожалению, новый заголовок не отображается автоматически, если я не перезагружу таблицу, раздел или строку. Действительно, если новое имя приводит к другой сортировке набора результатов, то срабатывает NSFetchedResultsChangeMove, и все в порядке, поскольку предоставленный код перезагружает весь раздел.
UITableView имеет метод reloadRowsAtIndexPaths: withRowAnimation, поэтому я попытался использовать его в блоке кода NSFetchedResultsChangeUpdate. Это действительно работает ... но документы для этого конкретного метода читаются так, как будто мне это не нужно (обратите внимание на последнюю строку):
При перезагрузке строки табличное представление запрашивает у источника данных новую ячейку для этой строки. Таблица анимирует эту новую ячейку, как анимирует старую строку. Вызовите этот метод, если вы хотите предупредить пользователя об изменении значения ячейки. Однако, если уведомление пользователя не важно, то есть вы просто хотите изменить значение, отображаемое в ячейке, вы можете получить ячейку для конкретной строки и установить ее новое значение.
И да, если я записываю, что происходит, когда
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
вызывается в NSFetchedResultsChangeUpdate, он может получить последнее значение «name» и установить его в textLabel ячейки. Имя просто не отображается в ячейке, если я не перезагружу его. Даже если я просто щелкну по ячейке, имя появится. Обратите внимание, что для воссоздания этого поведения необходимо создать новый управляемый объект и затем дать ему имя, которое заставит его сортировать FIRST в NSFetchedResultsController. Таким образом, NSFetchedResultsChangeMove не срабатывает (что действительно работает, поскольку перезагружает раздел).
Я что-то упустил или это ожидаемое поведение? «Обсуждение» reloadRowsAtIndexPaths наводит меня на мысль, что я должен иметь возможность просто установить textLabel ячейки без перезагрузки строки, раздела или таблицы.