代码之家  ›  专栏  ›  技术社区  ›  Simon

因nsManagedObjectContext保存而更新nsFetchedResultsController时延迟UITableView更新

  •  2
  • Simon  · 技术社区  · 14 年前

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

    我有类似于邮件中消息视图的上/下按钮。此行为会扰乱项目的顺序,我希望延迟此更改,直到用户出于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];
    }
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   TechZen    14 年前

    问题不在 NSFetchedResultsControllerDelegate 方法。只有当表可见时,某些内容更改了数据模型,这些方法才会起作用。

    您的问题是在表视图处于非屏幕和非活动状态时更改数据。表视图设计为自动显示给定给它们的数据模型。当您从细节视图返回到TableView时,它会自动重新加载其数据,该数据现在包含在细节视图中所做的更改。不管您如何向表提供数据,它都会这样做。

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

    但是,从UI设计的角度来看,我建议您重新考虑您的设计。如果在重新加载后才更改表,您将如何向用户发出要进行更改的信号?用户界面是否会突然无明显原因地更新?用户必须启动它吗?如果他们忘记了呢?

    我认为用户希望细节视图中所做的任何更改都能立即反映在TableView中,因为这实际上是所有TableView细节视图对的工作方式。例如,如果您在通讯簿的联系人详细信息中更改了联系人的姓名,则当您返回联系人列表时,该详细信息会立即反映出来。

        2
  •  0
  •   malhal Benzy Neez    8 年前

    我使用的一个技巧是,当你展示你的细节视图控制器时调用beginupdates,当它消失时调用endupdates。例如。

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetail"]){
    
            // configure detail controller
    
            // makes row appear after modal disappears.
            [self.tableView beginUpdates];
            [v setViewDidDissapear:^(BOOL animated) { // custom block added 
                [self.tableView endUpdates];
            }];
        }
    }