Search code examples
iosanimationnsfetchedresultscontroller

Disable animations produced by NSFetchedResultsController on batch update deleting


I'm currently using NSFetchedResultsController to display content in a UITableView instance.

At some point, I do a batch delete followed by a batch insert in Core Data. As a result, the NSFetchedResultsControllerDelegate proceed the insertion and deletion one by one. This gives a strange look to the GUI where you literally see that the rows are deleted or inserted one by one.

Is it possible to make an implementation of NSFetchedResultsControllerDelegate that clear or insert a batch of row in one time instead of doing it iteratively ?


Solution

    1. set delegate of NSFetchedResultsController to nil
    2. do your batch changes
    3. make NSFetchedResultsController refetch its content (i.e. performFetch:)
    4. set delegate of NSFetchedResultsController back to your viewController
    5. reload the tableView

    I use the usual lazy getter approach for my NSFetchedResultsController, so I can just set its instance variable to nil and the tableView reload will create a new one.

    e.g.:

    // returns a NSFetchedResultsController that has performed its fetch
    - (NSFetchedResultsController *)fetchedResultsController {
        if (_fetchedResultsController) {
            return _fetchedResultsController;
        }
        _fetchedResultsController = [NSFetchedResultsController alloc] initWith...
        if (![_fetchedResultsController performFetch:&error]) {
            ...
        }
        _fetchedResultsController.delegate = self;
        return _fetchedResultsController;
    }
    
    - (void)batchRequestWithoutAnimation {
        _fetchedResultsController.delegate = nil;
        // mass insert/delete
        _fetchedResultsController = nil;
        [self.tableView reloadData]; // tableView dataSource methods call 
                                     // [self fetchedResultsController], 
                                     // which will create a new one
    }