6

Ho un UITabbar con più controller al suo interno. Uno dei controller viene utilizzato per aggiungere eventi ai dati principali, mentre un altro controller viene utilizzato per visualizzare eventi come in un UITableView utilizzando NSFetchedResultsController.Come impedire a NSFetchedResultsController di aggiornare tableview quando il controller scompare?

Ecco il comportamento che vorrei ottenere: Dopo la scomparsa, UITableView interrompe l'aggiornamento e quando l'utente torna indietro, l'intera vista tabella viene ricaricata. In caso contrario, l'inserimento di eventi dall'altro controller richiede più tempo, poiché le nuove righe vengono create nello UITableView, anche se non sono visibili.

mi chiedo come posso ottenere questo comportamento, in quanto non sembra funzionare come mi aspetto che sarebbe stato:

Ho impostato il delegato del NSFetchedResultsController a zero in viewWillDisappear, e ripristinarlo in viewWillAppear, insieme a una chiamata a [UITableView reloadData];

In qualche modo, non vedo i nuovi dati e sospetto che ciò sia dovuto al modo in cui NSFetchedResultsController interrompe il recupero se non dispone di un delegato.

Come posso "sospendere" correttamente gli aggiornamenti a UITableView quando scompare, ma è ancora possibile vedere l'intero set di dati quando il controller riappare?

risposta

7

Provare a inviare performFetch: alla NSFetchedResultsController in viewWillAppear: dopo aver impostato il suo delegato di nuovo a self.

1

Invece di impostare la delegate del NSFetchedResultsController a zero in viewWillDisappear, provare a impostare un oggetto di NSFetchedResultsController a zero

+0

Sarebbe bello sapere perché downvote? – user427969

2

Penso che non sia necessario "sospendere" gli aggiornamenti della visualizzazione tabella. A NSFetchedResultsController per celle è visibile solo un UITableView. Se la vista tabella non è visibile, non verrà generato alcun aggiornamento.

Si è verificato se l'inserimento di eventi da un altro controller richiede più tempo? Ne dubito. Cosa dicono gli strumenti?

Se i metodi delegati vengono attivati, è comunque possibile controllare se la vista tabella è visibile prima di eseguire qualsiasi aggiornamento.

Successivamente, si fa esattamente come suggerito da rob: fare un performFetch: in viewWillAppear:.

+1

Anche se non ci sono veri aggiornamenti dell'interfaccia utente, 'beginUpdates' a' controllerWillChangeContent' e 'endUpdates' a' controllerDidChangeContent' stanno "congelando" il thread FRC per un po 'di tempo. –

0

E questo approccio approssimativo? Non testato.

@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]; 
    } 
}