rgamber
rgamber

Reputation: 5849

How to correctly implement NSFetchedResultsController.controllerDidChange()

I have a UIView which has a UITableView along with different components. Its corresponding UIViewController has the viewDidLoad() as follows:

Class Foo: UIViewController, NSFetchedResultsControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        /* some other stuff */

        // An instance of a class implementing UITableViewData Source
        // and NSFetchedResultsController. 
        // It also contains the instance of the  
        // NSFetchedResultsController.
        self.namesTable.dataSource = self.namesTableController  
        self.namesTableController.fetchedResultsController.delegate = self
    }

    // For updating the table when its content changes - NSFetchedResultsControllerDelegate
    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        self.namesTable.reloadData()
    }

    /* Other functions, etc, etc.... */

}

This arrangement works fine: when I add/remove entries to/from the table, the table reloads.

But I don't think that this is the right way of doing it, since the entire table is re-loaded every time when any change occurs. Seems like an overkill.

After looking online for several hours, I am not coming with anything. Can anyone point me to the right way of doing this? or am I doing it right?

Upvotes: 0

Views: 241

Answers (1)

Ian
Ian

Reputation: 12768

Although there is nothing "wrong" with reloadData() it is unnecessary to call it every time one object changes, as you stated. You can update only the content you want by implementing the other NSFetchedResultsControllerDelegate functions and using beginUpdates() and endUpdates() like so:

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}


func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch type {
    case NSFetchedResultsChangeType.Insert:
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    case NSFetchedResultsChangeType.Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    case NSFetchedResultsChangeType.Move:
        break
    case NSFetchedResultsChangeType.Update:
        tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    }
}

Upvotes: 1

Related Questions