5

Is there a way to update a UITableView sections and rows after changing the fetchedResultsControllers NSpredicate (and executing the fetch)? I would like to use controllerWillChangeContent delegate methods to update my table when the searchText in my searchBar is changed.

Currently in my app, these delegate methods only get called when changes in coredata occur. Not when changing the resultsController predicate & executing the fetch.

If I simply call [self.tableView reloadData] on each textchange, there are no animations and it blocks the experience a bit.

Or should I do something completely different to update the tableView contents on each search text entry change?

Tycho Pandelaar
  • 7,367
  • 8
  • 44
  • 70

4 Answers4

8

I've had another look into Apple's documentation and it looks like the NSFetchedResultsControllerDelegate methods are not called when a predicate has changed:

An instance of NSFetchedResultsController uses methods in this protocol to notify its delegate that the controller’s fetch results have been changed due to an add, remove, move, or update operations.

So, to answer my own question: It's not possible to use NSFetchedResultsControllerDelegate to update the table after NSFetchedResultsController predicate changes.

Tycho Pandelaar
  • 7,367
  • 8
  • 44
  • 70
  • An alternative approach could be to reformulate your problem in such a way that the change of the query is actually a change of the data. I tried some things with fetched properties and relationships to a central "query" object used in the predicate, which I would then change, but Core Data doesn't buy it. It only re-evaluates anything if I update the entities themselves. – mvds Jan 19 '12 at 01:22
0

Try to call [self.tableView reloadData] in

-(void)viewWillAppear:(BOOL)animated;
                 or
-(void)viewDidAppear:(BOOL)animated;
raaz
  • 12,410
  • 22
  • 64
  • 81
0

You could try using the UITableView method reloadSections:withRowAnimation: passing in an NSIndexSet with all of your sections. That way you should have the whole thing reload but still get the animation of your choice.

If you are adding and removing rows you will need to use insertSections:withRowAnimation: and removeSections:withRowAnimation:. If you're doing a number of changes at once you should also do them between calls to beginUpdates and endUpdates.

extremeboredom
  • 1,512
  • 12
  • 13
  • My search function also changes the nr of sections in the tableView. If I use reloadSections I get an error like ---"The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (61)"--- How should I deal with that? – Tycho Pandelaar Jan 01 '11 at 20:25
  • Also, Why aren't the NSFetchedResultsControllerDelegate methods 'didChangeSection' & 'didChangeObject' called when the fetchedResultsController is changed by an NSPredicate & execute fetch request? Those methods have the deleteSections & insertSections methods which should take care of the changes. – Tycho Pandelaar Jan 01 '11 at 21:24
  • I believe the delegate methods are only called as a result of a change in the model layer (such as when save: is called on the Managed Object Context). – extremeboredom Jan 01 '11 at 21:35
  • Thanx. I've had another look into Apple's doc and indeed, the documentation reflects that. – Tycho Pandelaar Jan 02 '11 at 11:12
0

From NSFetchedResultsController Class Reference:

Modifying the Fetch Request

You cannot simply change the fetch request to modify the results. If you want to change the fetch request, you must:

If you are using a cache, delete it (using deleteCacheWithName:). Typically you should not use a cache if you are changing the fetch request.

Change the fetch request. Invoke performFetch:.

Since you have changed the predicate, you must call performFetch: once again and then the delegate will handle updating the table from there.

Community
  • 1
  • 1
Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • Thanx for your response. My search works fine. I clean the cache, set the predicate & perform the fetch. Unfortunatly, I need to do a tableView reload to see the results. I am now looking for a way to only update removed/added sections & rows in the tableView. The NSFetchedResultsControllerDelegate is also working for me when I insert data into core data. But I am puzzled as to why the delegate methods don't fire when I execute a new request with a new predicate. – Tycho Pandelaar Jan 02 '11 at 10:58
  • This doesn't seem to be correct. I have to reload data after perform fetch even with a nil cache. – Bob Spryn Feb 20 '13 at 07:07
  • @BobSpryn You have to send `-reloadData` to the table view if you're not implementing the NSFRC delegate. – Mark Adams Feb 20 '13 at 17:41
  • @MarkAdams I am implementing the delegate. My understanding is updating the fetch request and re-fetching does NOT fire the delegate methods for changing content. See here: http://stackoverflow.com/a/14801165/287403 Unless Martin (and my testing) are incorrect. – Bob Spryn Feb 21 '13 at 04:49
  • You are correct that you will not get changes when changing the predicate and re-fetching. You will simply receive all of the objects as 'new' objects. – Mark Adams Feb 21 '13 at 06:42