6

Mam UITabbar z wieloma kontrolerami w nim. Jeden z kontrolerów jest używany do dodawania zdarzeń do danych podstawowych, podczas gdy inny kontroler służy do wyświetlania zdarzeń jak w UITableView przy użyciu NSFetchedResultsController.Jak zapobiec aktualizacji tabeli widoku NSFetchedResultsController, gdy kontroler zniknie?

Oto zachowanie, które chciałbym osiągnąć: Po zniknięciu, UITableView przestaje się aktualizować, a gdy użytkownik wróci, cały widok tabeli zostanie ponownie załadowany. W przeciwnym razie wstawianie zdarzeń z drugiego kontrolera trwa dłużej, ponieważ w wierszu UITableView są tworzone nowe wiersze, nawet jeśli nie są widoczne.

Zastanawiam się w jaki sposób można osiągnąć ten problem, gdyż nie wydają się działać jak oczekuję byłoby:

Mam ustawiony delegata NSFetchedResultsController do zera w viewWillDisappear i przywrócić go w viewWillAppear, wraz z połączeniem z [UITableView reloadData];

W pewnym sensie nie widzę nowych danych i podejrzewam, że wynika to ze sposobu, w jaki NSFetchedResultsController przestaje pobierać dane, jeśli nie ma delegata.

Jak mogę poprawnie "zawiesić" aktualizacje UITableView, gdy znika, ale nadal może zobaczyć cały zestaw danych po ponownym wyświetleniu kontrolera?

Odpowiedz

7

Spróbuj wysłać performFetch: do NSFetchedResultsController w viewWillAppear: po ustawieniu jej delegata z powrotem do self.

1

Zamiast ustawiania delegate z NSFetchedResultsController do zera w viewWillDisappear, spróbuj ustawić przedmiot NSFetchedResultsController do zera

+0

Dobrze by było wiedzieć, dlaczego w dół? – user427969

2

Myślę, że nie musisz "zawieszać" aktualizacji widoku tabeli. A UITableView będzie jednak wymagać tylko danych z komórek NSFetchedResultsController dla widocznych. Jeśli widok tabeli nie jest widoczny, żadne aktualizacje nie zostaną uruchomione.

Czy testowałeś, czy wstawianie zdarzeń z innego kontrolera naprawdę trwa dłużej? Wątpię. Co mówi Instruments?

Jeśli metody delegatów zostaną uruchomione, nadal można sprawdzić, czy widok tabeli jest widoczny przed wykonaniem jakichkolwiek aktualizacji.

Później robisz dokładnie tak, jak sugeruje to rob: czy performFetch: w viewWillAppear:.

+1

Nawet jeśli nie ma prawdziwych aktualizacji UI, 'beginUpdates' at" controllerWillChangeContent' i 'endUpdates' at" controllerDidChangeContent' są "zamrożeniem" wątku FRC przez pewien czas. –

0

Co z tym prostym podejściem? Nie testowałem tego.

@property (nonatomic) BOOL bruteForceReload; 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    self.bruteForceReload = NO; 
} 

-(void)viewDidDisappear:(BOOL)animated { 
    [super viewDidDisappear:animated]; 
    self.bruteForceReload = YES; 
} 

-(void)setBruteForceReload:(BOOL)bruteForceReload { 
    _bruteForceReload = bruteForceReload; 
    if (_bruteForceReload) { 
     [self.tableView reloadData]; 
    } 
} 

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

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 
{ 
    if (!self.bruteForceReload) { 
     switch(type) { 
      case NSFetchedResultsChangeInsert: 
       [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

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

      default: 
       return; 
     } 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    if (!self.bruteForceReload) { 
     UITableView *tableView = self.tableView; 

     switch(type) { 
      case NSFetchedResultsChangeInsert: 
       [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

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

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

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    if (!self.bruteForceReload) { 
     [self.tableView endUpdates]; 
    } else { 
     [self.tableView reloadData]; 
    } 
} 
Powiązane problemy