Reputation: 4636
I am working on how to reorder cells in CoreData using FRC, I came across many posts which suggest to use a order attribute and update this accordingly, one such code is here below
While inserting New Object I have to set display Order and increment it according
here is the code for it
- (void)insertNewObject
{
Test *test = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.managedObjectContext];
NSManagedObject *lastObject = [self.controller.fetchedObjects lastObject];
float lastObjectDisplayOrder = [[lastObject valueForKey:@"displayOrder"] floatValue];
[test setValue:[NSNumber numberWithDouble:lastObjectDisplayOrder + 1.0] forKey:@"displayOrder"];
}
- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath;
{
NSMutableArray *things = [[fetchedResultsController fetchedObjects] mutableCopy];
// Grab the item we're moving.
NSManagedObject *thing = [[self fetchedResultsController] objectAtIndexPath:sourceIndexPath];
// Remove the object we're moving from the array.
[things removeObject:thing];
// Now re-insert it at the destination.
[things insertObject:thing atIndex:[destinationIndexPath row]];
// All of the objects are now in their correct order. Update each
// object's displayOrder field by iterating through the array.
int i = 0;
for (NSManagedObject *mo in things)
{
[mo setValue:[NSNumber numberWithInt:i++] forKey:@"displayOrder"];
}
[things release], things = nil;
// [managedObjectContext save:nil];
NSError *error = nil;
if (![managedObjectContext save:&error])
{
NSString *msg = @"An error occurred when attempting to save your user profile changes.\nThe application needs to quit.";
NSString *details = [NSString stringWithFormat:@"%@ %s: %@", [self class], _cmd, [error userInfo]];
NSLog(@"%@\n\nDetails: %@", msg, details);
}
// re-do the fetch so that the underlying cache of objects will be sorted
// correctly
if (![fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
But suppose I have 100 items, and I delete any one item from middle then I have to recalculate the displayOrder, which I think is not feasible. Is there any alternative way to do this process
Regards Ranjit
Upvotes: 1
Views: 374
Reputation: 150605
Why do you think you need to recalculate the index number?
The items are arranged according to the sort order you apply.
If you supply an ascending sort order, and you supply a number, then you will get the right sorting. What you don't need is a direct correspondance between the number you use to order your items and the index of the item in the array. For example: If your ordering numbers are
1 2 3 4
Then when you fetch them and sort them they will appear in this order. But if the ordering numbers are different, they will still appear in the same order.
1 3 5 7
it doesn't matter that numbers are missing, because they are only used for sorting, not recording a position.
Now, let's imagine you have 4 items sorted according to an index.
1 2 3 4
Now delete the second item
1 3 4
You have 1 less item, but they are still in the same order. Say you add an item to the end:
1 3 4 5
Now imagine you want to move the item at the end to be in the third position. This is where you ask yourself another question: Why does the ordering index have to be an integer? If you use floats, you can see that it is easy to calculate a new index as the mid point between the number before and the number after. So, After moving the item at the end to be in the 3rd position, this is what the ordering indexes will look like:
1.0 3.0 3.5 4.0
How about adding a number in the second position. In this case the midpoint is easy to calculate:
1.0 2.0 3.0 3.5 4.0
So. There is nothing wrong with using an ordering index. It doesn't need to be an integer, so when you delete an item you don't have to go through and calculate all the indexes again.
Now, it is likely that these floats will grow ungainly, but you can run periodic renumberings in your app's downtime, or during updates when users expect a bit of set up to happen.
Upvotes: 4