Reputation: 8715
In Core Data I have one to many relationship - each layout has many lines:
I am trying to display data inside a table view by grouping into layouts:
Layout Nr 2342 (with orderPosition 1)
Line 1
Line 2
Line …
Layout Nr 2123 (with orderPosition 2)
Line 1
Line …
…
I am using NSFetchedResultsController
that I create like this:
NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];
NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setSortDescriptors:@[orderPositionDescriptor]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
[fetchRequest setPredicate:predicate];
self.fetchController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"layout.groupNumber"
cacheName:nil];
So I set fetch controller to group in sections by layout groupNumber, I also set sort descriptor to order by layout position (each layout has its own position). As soon as data is added to core data, it is displayed in the table view. Everything works great, till the moment when I try to change NSFetchRequest
predicate of the existing NSFetchedResultsController
:
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='%@'",section]];
[self.fetchController.fetchRequest setPredicate:predicate];
I set exactly the same section in the predicate as it was already set and the data after performFetch
displayed in the table is still the same, but layouts (table sections) changes position in the table and lines are displayed in wrong layouts (basically no oder). I figured out that if I set the first sort descriptor the same as sectionNameKeyPath - "layout.groupNumber", then everything works even if I change predicate. But obviously it is not ordered by orderPosition what I want to achieve. Is there any solution for that? Any help would be appreciated.
Upvotes: 0
Views: 526
Reputation: 3791
If you are using sections in your table view, and sorting your table view data, it is important to understand that the first sort descriptor must be identical to the sectionNameKeyPath.
As such I recommend you change your code to be something similar to this...
NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];
//new line of code following...
NSSortDescriptor *sectionNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.groupNumber" ascending:YES];
NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
//altered line of code following...
[fetchRequest setSortDescriptors:@[sectionNameDescriptor, orderPositionDescriptor]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
[fetchRequest setPredicate:predicate];
self.fetchController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"layout.groupNumber"
cacheName:nil];
I have read about this but cannot recall where... so no documentation reference I'm sorry.
Does this help?
Upvotes: 1
Reputation: 8715
I found a workaround of my problem. Because each layout group number has unique order position, solution is to group not by groupNumber, but by orderPosition. In that case I can specify orderPosition as the first (and the only) sort descriptor. In case someone else has other better solution, it would be still interesting to hear it.
NSEntityDescription *entity = [NSEntityDescription entityForName:@“Line” inManagedObjectContext:managedObjectContext];
NSSortDescriptor *orderPositionDescriptor = [[NSSortDescriptor alloc] initWithKey:@"layout.orderPosition" ascending:YES];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setSortDescriptors:@[orderPositionDescriptor]];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"section=='my_section'"]];
[fetchRequest setPredicate:predicate];
self.fetchController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"layout.orderPosition"
cacheName:nil];
Upvotes: 0