2011-09-25 19 views
32

Come vorresti un anime - reloadData su UITableView? La fonte dei dati è UIFetchedResultsController quindi non posso giocare con – insertSections:withRowAnimation:, – deleteSections:withRowAnimation: avvolto in – beginUpdates, – endUpdates.Animato reloadData su UITableView

MODIFICA: Voglio chiamare - reloadData dopo il ripristino NSFetchedResultsController.

+3

duplicato di questo - http: // stackover flow.com/questions/419472/have-a-reloaddata-for-a-ableable-animate-when-changing - buone risposte lì –

risposta

83

ho fatto metodo categoria.

- (void)reloadData:(BOOL)animated 
{ 
    [self reloadData]; 

    if (animated) { 

     CATransition *animation = [CATransition animation]; 
     [animation setType:kCATransitionPush]; 
     [animation setSubtype:kCATransitionFromBottom]; 
     [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
     [animation setFillMode:kCAFillModeBoth]; 
     [animation setDuration:.3]; 
     [[self layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"]; 

    } 
} 
+0

Bella soluzione se hai bisogno di animazioni personalizzate – voromax

+0

Incredibile soluzione!! – Jason

+0

Impressionante soluzione! Ho solo una cosa da aggiungere.Nel mio caso si sono verificati dei problemi perché il TableView prima del reloadData è stato fatto scorrere fino in fondo, quindi quando è avvenuta l'animazione ha rovinato tutte le celle e il frame del tavolo. Potrei risolverlo assicurandomi che il TableView sia stato fatto scorrere tutto in alto prima del reloadData: [self scrollRectToVisible: CGRectMake (0, 0, 1, 1) animato: NO]; – Pauls

9

Non è possibile animare reloadData. Dovrai utilizzare i metodi di visualizzazione tabella insert..., delete..., move... e reloadRows... per renderlo animato.

Questo è piuttosto semplice quando si utilizza un NSFetchedResultsController. La documentazione per NSFetchedResultsControllerDelegate contiene una serie di metodi di esempio che basta per adattarsi al vostro proprio codice:

- (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]; 
} 
+1

Mi dispiace non averlo menzionato ho bisogno di ricaricare i dati della tabella dopo il "refetch" NSFetchedResultsController' " . Penso che potrebbe essere fatto con alcune animazioni 'CALayer' sull'intero' UITableView' ... Qualcosa come il livello di visualizzazione tabella duplicato, refetch, ricaricare dati, animare layer off ... – user500

27

È possibile effettuare un'animazione di base del reloadData utilizzando:

// Reload table with a slight animation 
[UIView transitionWithView:tableViewReference 
        duration:0.5f 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^(void) { 
    [tableViewReference reloadData]; 
} completion:NULL]; 
+0

In qualsiasi altra transizione, i dati della vista tabella non vengono ricaricati finché non si inizia lo scorrimento. Qualche idea del perché? –

+1

Quando si aggiorna la tabella non nel flusso principale, la tabella potrebbe non essere aggiornata automaticamente. In questi casi è possibile utilizzare: [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; – Vincent

+0

Questo va nel blocco di animazione? –

5

ho creato un metodo UITableView categoria sulla base di soluzione da this link.

Dovrebbe ricaricare tutte le sezioni della tabella. Puoi giocare con le opzioni UITableViewRowAnimation per i diversi effetti di animazione.

- (void)reloadData:(BOOL)animated 
{ 
    [self reloadData]; 

    if (animated) 
    { 
     [self reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.numberOfSections)] withRowAnimation:UITableViewRowAnimationBottom]; 
    } 
} 
5
typedef enum { 
    UITableViewRowAnimationFade, 
    UITableViewRowAnimationRight, 
    UITableViewRowAnimationLeft, 
    UITableViewRowAnimationTop, 
    UITableViewRowAnimationBottom, 
    UITableViewRowAnimationNone, 
    UITableViewRowAnimationMiddle, 
    UITableViewRowAnimationAutomatic = 100 
} UITableViewRowAnimation; 

e il metodo:

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; 
14

Si può semplicemente chiamare questa linea quando si desidera ricaricare l'intera tabella con un'animazione:

NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]); 
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range]; 
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade]; 
+0

Bello! Cercavo una soluzione pulita questa è per quelli che non vogliono chiamare il bruto reloadData .... – DogCoffee

1

si potrebbe desiderare di utilizzare:

Objective-C

/* Animate the table view reload */ 
[UIView transitionWithView:self.tableView 
        duration:0.35f 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^(void) 
{ 
     [self.tableView reloadData]; 
} 
       completion:nil]; 

Swift opzioni

UIView.transitionWithView(tableView, 
          duration:0.35, 
          options:.TransitionCrossDissolve, 
          animations: 
{() -> Void in 
    self.tableView.reloadData() 
}, 
          completion: nil); 

Animazione:

TransitionNone TransitionFlipFromLeft TransitionFlipFromRight TransitionCurlUp TransitionCurlDown TransitionCrossDissolve TransitionFlipFromTop TransitionFlipFromBottom

Reference

Problemi correlati