2

我正在使用带有 NSFetchedResultsController 的谓词对 UITableView 进行排序。但是,当我在详细视图中进行更改并保存它时,我更改的对象立即被放置在 UITableView 中的新位置。

我有类似于 Mail 中消息视图的向上/向下按钮。这种行为会打乱项目的顺序,我想推迟这种变化,直到用户出于 UX 原因退出 UITableView。我在 UITableViewController 中实现了 NSFetchedResultsControllerDelegate 方法。有没有简单/聪明的方法来做到这一点?

编辑:下面是在 UITableViewController 中实现的 NSFetchedResultsControllerDelegate 方法。

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                          withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
                    atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}
4

2 回答 2

3

问题不在于NSFetchedResultsControllerDelegate方法。这些方法只有在表格可见时更改数据模型时才会发挥作用。

您的问题是您在表格视图处于屏幕外且处于非活动状态时更改了数据。表格视图旨在自动显示给它们的数据模型。当您从详细视图返回到 tableview 时,它会自动重新加载其数据,这些数据现在包含在详细视图中所做的更改。无论您如何向表格提供数据,它都会这样做。

阻止表格显示更改直到您希望显示更改的唯一方法是在您希望更改出现之前不将数据添加到数据模型中。您必须将数据从详细视图传递回非托管对象中的表,并在您希望它出现时在表视图控制器中创建托管对象。

但是,从 UI 设计的角度来看,我建议您重新考虑您的设计。如果您在重新加载表之前不更改表,您将如何向用户发出您将进行更改的信号?用户界面会无缘无故地突然更新吗?用户是否必须启动它?如果他们忘记了怎么办?

我认为用户会期望在详细视图中所做的任何更改都会立即反映在 tableview 中,因为这实际上是所有 tableview-detailView 配对的工作方式。例如,如果您更改通讯录的联系人详细信息中的联系人姓名,当您返回联系人列表时,该联系人会立即反映。

于 2010-07-15T13:04:30.173 回答
0

我使用的一个技巧是在表格视图控制器消失时调用 beginUpdates,然后在它出现时调用 endUpdates:

- (void)viewWillAppear:(BOOL)animated{
    [self.tableView endUpdates];
    [super viewWillAppear:animated];
}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.tableView beginUpdates];
}

这样,获取控制器可以继续工作,您可以继续将更新用于其他事情。

于 2016-03-23T01:16:42.873 回答