The only solution that worked for me: Thomas Worrall Blog: Reordering Strings in a UITableView with Master Data
First of all, you need to create an attribute in your NSManagedObject in order to hang the last order of your object.
@interface MyEntity : NSManagedObject @property (nonatomic, retain) NSNumber * lastOrder; @end
Then declare the property in your ViewController.m:
@interface ViewController () @property (nonatomic) BOOL isReordering; @end
In the tableView: moveRowAtIndexPath: toIndexPath: method , control the changes in the temporary array:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { _isReordering = YES; NSMutableArray *arrayNewOrder = [[_fetchedResultsController fetchedObjects] mutableCopy]; MyEntity *myManagedObject = [arrayNewOrder objectAtIndex:fromIndexPath.row]; [arrayNewOrder removeObjectAtIndex:fromIndexPath.row]; [arrayNewOrder insertObject:myManagedObject atIndex:toIndexPath.row]; for (int i=0; i < [arrayNewOrder count]; i++) { myManagedObject = [arrayNewOrder objectAtIndex:i]; myManagedObject.lastOrder = [NSNumber numberWithInt:i]; } _isReordering = NO; NSError *error; BOOL success = [self.fetchController performFetch:&error]; if (!success) {
Thomas explained how to fetch and maintain context:
I'm not quite sure why sampling is needed first, but he recorded a ton of crazy mistakes when I did this!
The last trick handles the delegate method NSFetchedResultsController : didChangeObject: atIndexPath: forChangeType: newIndexPath: in particular in NSFetchedResultsChangeMove:
case NSFetchedResultsChangeMove: { if (!_isReordering) { [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; } break; }
It worked for me! Hope this helps you!
source share