I have an UITableView and a UISegmentControl in my view controller. The view controller has two segments. When the user clicks on a segment, I refine the data in the viewController, and it should update in the UITableView. This doesn't work.
The data is displayed using a NSFetchedResultsController, whoses datasource is a CoreData table. They use the same NSSortDescriptor, but not the same predicate.
I observed that when I change the NSSortDescriptor, it works, so this objects is the root of the problem.
When the user clicks on a segment, I call this code:
self.fetchedResultsController = nil;
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
And it updates the NSFetchedResultsController this way:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
//get the segment index:
NSUInteger selectedState = self.chooseTableSegmentedControl.selectedSegmentIndex;
//Update the fetched result consequently:
NSManagedObjectContext *context = self.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:NO];
NSPredicate *predicate;
if (selectedState == 0) {
[fetchRequest setSortDescriptors:@[dateDescriptor]];
} else if (selectedState == 1) {
predicate = [NSPredicate predicateWithFormat:
@"postedByUser == 0"];
[fetchRequest setSortDescriptors:@[dateDescriptor]];
}
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:7];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:@"Root"];
_fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
Any idea? Thanks a lot!
After creating a new fetched results controller and calling performFetch
, you have to reload the table view with reloadData
. performFetch
does not trigger the FRC delegate methods.
Update: A FRC cache must be deleted when the fetch request changes (using deleteCacheWithName:
). But the cache is only useful in connection with a sectionNameKeyPath:
, so you can set cacheName:nil
as well to solve the problem.