I can create new managed objects inside my app, in a separate view I have a table view which shows all the objects I have.
When I create a new managed object (in a total
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.
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
.
In case someone having the same issue, as I just had it. I have tried the above solution with green tick, but it wouldn't work for me. I have followed Apple's code and everything went fine.
simply, just implement the three "Fetchcontroller" delegate functions
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
print("")
self.configureCell(self.tableView.cellForRowAtIndexPath(indexPath!)!, indexPath: indexPath!)
case .Move:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
self.tableView.insertRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
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()
}
}