2

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

У меня есть кнопки вверх/вниз, похожие на вид сообщения в 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]; 
} 
+0

Это звучит странно для меня. Можете ли вы опубликовать некоторый код, относящийся к обновлению подробного представления и некоторого кода UITableView? – vodkhang

+0

Настройка происходит, когда пользовательский UIControl изменяет состояние, контроллер представления подробностей уведомляется через KVO, будет изменять объект NSManagedObject и запускать сохранение в NSManagedObjectContext. Когда NSManagedObjectContext сохраняет, я думаю, что он уведомляет NSFetchedResultsController, что все изменилось. Затем NSFetchedResultsController сообщает делегату, что изменилось. У меня есть методы NSFetchedResultsControllerDelegate, которые я реализовал в контроллере табличного представления выше. Спасибо – Simon

ответ

2

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

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

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

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

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

+0

Спасибо. Я подумывал о создании промежуточной области, подобной тому, что вы сказали, и передать поэтапные изменения в нужное время. Что касается перспективы пользовательского интерфейса, таблица сортируется по рейтингу для каждого элемента. Когда рейтинг меняется, он полностью меняет ваше место в списке, поэтому использование кнопок next/prev до и после изменения рейтинга даст разные результаты.Кроме того, мне нравится иметь возможность обрабатывать прецедент, когда пользователь может пройти через все неоцененные предметы, чтобы оценить их, не потеряв своего места. Я не полностью убежден, что дизайн абсолютно правильный. Как вы думаете? – Simon

+1

Если я понимаю ваш дизайн, я думаю, вы можете добавить не отображаемый рейтинг в свою модель данных, которую вы используете для сортировки таблицы. Когда пользователь вносит изменения, вы изменяете отображаемую оценку, но не показываете нерасположенный рейтинг, чтобы объект оставался в том же порядке пользовательского интерфейса, который был перед изменением. Тогда у вас может быть кнопка «сортировка таблицы», которая скопировала бы отображаемую оценку в нерасположенный рейтинг и поместила все в правильном порядке. – TechZen

+0

Ах, это имеет большой смысл. Благодаря! – Simon

0

Один трюк, который я использовал, это вызвать 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]; 
     }]; 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^