使用获取结果控制器重新排序核心数据中的单元格

时间:2012-11-02 14:25:24

标签: ios ios5 core-data nsfetchedresultscontroller

我正在研究如何使用FRC重新排序CoreData中的单元格,我遇到了许多建议使用订单属性并相应更新的帖子,其中一个代码如下所示

插入新对象时,我必须设置显示顺序并根据

递增

这是它的代码

- (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();
    }
}

但是假设我有100个项目,我从中间删除任何一个项目然后我必须重新计算displayOrder,我认为这是不可行的。是否有其他方法可以执行此过程

此致 兰吉特

1 个答案:

答案 0 :(得分:4)

为什么您认为需要重新计算索引号?

根据您应用的排序顺序排列项目。

如果您提供升序排序,并且提供了一个数字,那么您将获得正确的排序。您不需要的是您用于订购商品的数字与数组中商品的索引之间的直接对应关系。例如:如果您的订购号是

1 2 3 4

然后,当您获取它们并对它们进行排序时,它们将按此顺序显示。但如果订购号不同,它们仍会以相同的顺序出现。

1 3 5 7

数字丢失并不重要,因为它们仅用于排序,而不是记录位置。

现在,让我们假设您有4个项目根据索引排序。

1 2 3 4

现在删除第二项

1 3 4

您减少了一项,但它们的顺序仍然相同。假设你在最后添加一个项目:

1 3 4 5

现在想象一下,您想要将项目最后移动到第三个位置。这就是你问自己另一个问题:为什么排序索引必须是整数?如果使用浮点数,您可以看到很容易将新索引计算为前一个数字和后一个数字之间的中间点。因此,在最后将项目移动到第3个位置后,这就是订购索引的样子:

1.0 3.0 3.5 4.0

如何在第二个位置添加数字。在这种情况下,中点很容易计算:

1.0 2.0 3.0 3.5 4.0

因此。使用排序索引没有任何问题。它不需要是整数,因此当您删除项目时,您不必经历并再次计算所有索引。

现在,这些花车可能会笨拙地增长,但是您可以在应用程序的停机时间内或在用户期望进行一些设置的更新期间定期重新编号。