How to prevent NSFetchedResultsController from updating when the controller disappears?

I have a UITabbar with multiple controllers. One of the controllers is used to add events to the main data, and the other controller is used to display events, as in a UITableView, using the NSFetchedResultsController .

Here is the behavior I would like to achieve: After the disappearance, the UITableView stops updating, and when the user returns, the entire view of the table is reloaded. Otherwise, inserting events from another controller takes longer because new rows are created in the UITableView , even if they are not visible.

I am wondering how I can achieve this behavior since it does not seem to work as I expect it to be:

I set the NSFetchedResultsController delegate to nil in viewWillDisappear and restored it to viewWillAppear along with a call to [UITableView reloadData] ;

Somehow I do not see new data and suspect that this is due to the way NSFetchedResultsController stops the selection if it does not have a delegate.

How can I correctly “pause” updates to a UITableView when it disappears, but can still see the entire dataset when the controller reappears?

+6
source share
4 answers

Try sending performFetch: to NSFetchedResultsController in viewWillAppear: after you return it to the delegate in self .

+7
source

I think you do not need to “pause” table view updates. A UITableView will in any case only request data from the NSFetchedResultsController for visible cells. If the table view is not displayed, updates will not start.

Have you experienced if inserting events from another controller takes longer? I doubt it. What do the tools say?

If your delegation methods are running, you can still check to see if the table view is visible before performing any updates.

After that, you do what rob suggested: do a performFetch: in viewWillAppear:

+2
source

Instead of setting the delegate in NSFetchedResultsController to nil in viewWillDisappear , try setting the NSFetchedResultsController to nil

+1
source

How about this rude approach? Not verified.

 @property (nonatomic) BOOL bruteForceReload; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.bruteForceReload = NO; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; self.bruteForceReload = YES; } -(void)setBruteForceReload:(BOOL)bruteForceReload { _bruteForceReload = bruteForceReload; if (_bruteForceReload) { [self.tableView reloadData]; } } - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { if (!self.bruteForceReload) { [self.tableView beginUpdates]; } } - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { if (!self.bruteForceReload) { switch(type) { case NSFetchedResultsChangeInsert: [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeDelete: [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; break; default: return; } } } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { if (!self.bruteForceReload) { UITableView *tableView = self.tableView; switch(type) { case NSFetchedResultsChangeInsert: [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeDelete: [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; break; case NSFetchedResultsChangeUpdate: [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; break; case NSFetchedResultsChangeMove: [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } } } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { if (!self.bruteForceReload) { [self.tableView endUpdates]; } else { [self.tableView reloadData]; } } 
0
source

All Articles