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)?
I'd an an attribute to the Core Data entity, let's say it's an
NSNumber
calledsortOrder
.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 extrasortDescriptor
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.)
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:
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:
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, useobjectAtIndex
intableView: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:
See also