Задержка обновления UITableView, когда NSFetchedResultsController обновляется из-за сохранения NSManagedObjectContext - PullRequest
2 голосов
/ 15 июля 2010

Я сортирую UITableView, используя предикат с NSFetchedResultsController. Но когда я внесу изменение в подробный вид и сохраню его, объект, который я изменил, сразу же помещается в новое место в UITableView.

У меня есть кнопки вверх / вниз, похожие на сообщения в Mail. Такое поведение нарушает порядок элементов, и я бы хотел отложить это изменение, пока пользователь не вернется к UITableView по причинам UX. Я реализовал методы NSFetchedResultsControllerDelegate в UITableViewController. Есть ли простой / умный способ сделать это?

Редактировать: ниже приведены методы NSFetchedResultsControllerDelegate, реализованные в UITableViewController.

- (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 ]

3 голосов
/ 15 июля 2010

Проблема не в NSFetchedResultsControllerDelegate методах. Эти методы вступают в действие только в том случае, если что-то меняет модель данных, когда таблица видна.

Ваша проблема в том, что вы изменяете данные, когда табличное представление находится за пределами экрана и неактивно. Табличные представления предназначены для автоматического отображения заданной им модели данных. Когда вы возвращаетесь в табличное представление из подробного представления, оно автоматически перезагружает свои данные, которые теперь содержат изменения, сделанные в подробном представлении. Это будет сделано независимо от того, как вы предоставили данные в таблицу.

Единственный способ запретить отображению изменений в таблице до тех пор, пока вы этого не хотите, - не добавлять данные в модель данных до тех пор, пока вы не захотите, чтобы это изменение появилось. Вам нужно будет передать данные из подробного представления обратно в таблицу в неуправляемом объекте и создать управляемый объект в контроллере табличного представления, когда вы захотите, чтобы он появился.

Однако, с точки зрения дизайна пользовательского интерфейса, я предлагаю вам пересмотреть свой дизайн. Если вы не измените таблицу до тех пор, пока она не перезагрузится, как вы будете оповещать пользователей о том, что вы собираетесь внести изменения? Будет ли интерфейс внезапно обновляться без видимой причины? Придется ли пользователю инициировать это? Что если они забудут?

Я думаю, что пользователи будут ожидать, что любые изменения, внесенные в детальном представлении, будут немедленно отражены в табличном представлении, потому что именно так работают практически все пары tableview-detailView. Например, если вы измените имя контакта в контактной информации адресной книги, которое будет отражено сразу после возврата к списку контактов.

0 голосов
/ 23 марта 2016

Один прием, который я использовал, - это вызывать 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];
        }];
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...