Reputation: 113757
What are the steps that I need to perform to implement user-defined ordering in a UITableViewController
with Core Data as the backing store?
Do I still need to respond to -tableView:moveRowAtIndexPath:fromIndexPath:toIndexPath:
or is the model re-ordering handled automatically by the table view? Can I just check the "Ordered" checkbox in the Core Data model file and expect it to transmit the changes from the table view to the store, or do I have to do more? Do I have to change the way my fetchedResultsController
gets it's objects (e.g. add a sort descriptor)?
Upvotes: 10
Views: 4049
Reputation: 8695
You don't need to abandon NSFetchedResultsController or NSOrderedSet. If you stick with NSOrderedSet, the easy way is to just add a method to your objects NSManagedObject subclass. So for instance, if you have an object Book with an ordered set of Chapters, you can add a method to the Chapters object:
- (NSUInteger)indexInBookChapters
{
NSUInteger index = [self.book.chapters indexOfObject:self];
return index;
}
Tip: Add this to a category so it doesn't get overwritten by CoreData auto generated code.
Then you can use this method in your sort descriptor for your NSFetchedResultsController:
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"indexInBookChapters" ascending:YES]];
Upvotes: 8
Reputation: 5371
The best practice here is to NOT use fetchedResultsController
because it requires a sort descriptor, as you mentioned. You could use a dummy property but this is clearly not good practice. Instead, use objectAtIndex
in tableView:cellForRowAtIndexPath:
and reload the table data when you need to, perhaps using Key-Value Observing, though depending on your use case there may be simpler and less crash-prone approaches.
And yes, you will have to implement tableView:moveRowAtIndexPath:fromIndexPath:toIndexPath:
Upvotes: 1
Reputation: 6414
I'd an an attribute to the Core Data entity, let's say it's an NSNumber
called sortOrder
.
When you init a new object in this list, assign the sortOrder
in increasing order, so that the default sort order is there.
Last, tell your fetchedResultsController
to use an extra sortDescriptor
for this sortOrder attribute.
When a user adjusts the position of an entry, you could set the sortOrder
to the mean of the entry before and after it.
(Just an idea --- I haven't dealt with this problem or had to implement it, but was considering it for my project down the line.)
Upvotes: 0