0

我有一个 UITableView,它被配置为允许在编辑模式下在部分之间移动行。该表使用 NSFetchedResultsController 支持

很难描述我看到的问题,但本质上是:

1)用户开始拖动一行

2)其他行在桌子周围拖动时移开

3)用户释放触摸,我通过适当更新 ManagedObject 来响应 moveRowAtIndexPath: 回调(下面的代码)

4)现在,由于某些原因,其他行动画回到用户开始拖动之前的位置。也就是说,所有人都会向上或向下移动一排,回到原来的位置,而不是停留在新的位置。

一段时间后,通常在 0.5 秒到 3 秒之间,NSFetchResultsController 决定让我更新移动的单元格。在这一点上,我最终调用了 [table beginUpdates] 和 [table endUpdates] 并且行移动到它们应该执行的位置。

现在,来自 NSFetchResultsController 的延迟回调是一个奇怪的问题,但这似乎很重要。重要的是 UITableView 不会将行留在新位置,并且需要开始/结束更新调用才能将行放在应有的位置。我是否应该在此回调中做其他事情:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
    NSLog(@"UI is moving row from [%d, %d] to [%d, %d]", fromIndexPath.section, fromIndexPath.row, toIndexPath.section, toIndexPath.row);

    self.inManualReorder = YES;

    // Here I update the underlying object, code is not relevant as this works.

    ...

    // I've tried saving the context here and delaying it untill later on. It doesn't affect
    // the behavior in question.

    NSError *error = nil;
    if (![self.managedObjectContext save:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    self.inManualReorder = NO;

    NSLog(@"UI finished moving row");
}
4

3 回答 3

1

我以前也有同样的问题。来自斯坦福 CS193p 的 CoreDataTableViewController 使用 suspendAutomaticTrackingOfChangesInManagedObjectContext 属性正常工作。它在手动更新期间忽略来自托管对象上下文的更新。

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
    {
        NSError *error = nil;

        [self setSuspendAutomaticTrackingOfChangesInManagedObjectContext:YES];

        // yourown code here ...

        [self setSuspendAutomaticTrackingOfChangesInManagedObjectContext:NO];
        [self performFetch];
    }
于 2013-02-13T00:25:46.373 回答
0

您如何保存获取的结果?在数组中?

似乎在此数组更新之前表正在重新加载,然后在更新后再次加载(不久之后)

尝试实施

- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;

像您当前一样更新您的托管对象,但将它们保存在此方法中,然后获取结果并设置您的数组。最后,在您的 UITableView 上调用 reloadData (谁的委托(即您的视图控制器)访问该结果数组。

编辑:您是否在更新块内进行表更新,即

[tableView beginUpdates];

// ...Move cell...

[tableView endUpdates];
于 2012-06-15T12:15:19.587 回答
0

我已经找到了。

在对 controllerWill(Did)ChangeContent 的回调中,我调用了 begin(end)Updates。如果重新排序来自手动干预,我不应该这样做:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    if (!self.inManualReorder)
        [self.tableView beginUpdates];
}

我正在检查 didChangeObject: 回调的这个标志,但不是这些......

于 2012-06-20T19:33:42.627 回答