Refresh NSFetchedResultsController data?
You are setting your UITableViewController
as the NSFetchedResultsControllerDelegate
. That's good. Now try to implement the controllerDidChangeContent:
method in the TableViewController like so:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView reloadData];
}
Your NSFetchedResultsController
will listen to removed or new objects in Core Data and notify its delegate (your TableViewController) of changes. Check the Core Data template project in Xcode to implement this even better with add and removal animations in the UITableView
.
Be sure to add the didChangeObject method:
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id) anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self.tableView
cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *note = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [note valueForKey:@"title"];
}
The new managed object showed up in the table view after this.
Updated to latest swift 4.2 and Xcode 10.
extension MyListController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
self.tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
self.tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
self.tableView.reloadRows(at: [indexPath!], with: .fade)
case .move:
self.tableView.deleteRows(at: [indexPath!], with: .fade)
self.tableView.insertRows(at: [indexPath!], with: .fade)
}
}
func controller(_ controller:
NSFetchedResultsController<NSFetchRequestResult>, didChange
sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex
sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch (type) {
case .insert:
self.tableView.insertSections([sectionIndex], with: .fade)
case .delete:
self.tableView.deleteSections([sectionIndex], with: .fade)
case .move:
self.tableView.deleteSections([sectionIndex], with: .fade)
self.tableView.insertSections([sectionIndex], with: .fade)
case .update:
self.tableView.reloadSections([sectionIndex], with: .fade)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()
}
}