2015-04-16 15 views
9

Mi piacerebbe creare un'animazione speciale per quando sto ricaricando le righe di un UITableView. Il fatto è che non voglio usare questa animazione tutto il tempo, perché a volte utilizzo l'animazione incorporata per ricaricare le righe.Come sovrascrivere correttamente reloadRowsAtIndexPaths: withRowAnimation?

Quindi, come posso fare questo? Sovrascrivendo nella mia implementazione UITableView? Come?

O forse c'è un modo migliore per ottenere la mia animazione mentre ricarico una riga?

risposta

5

Penso che non si debba ignorare lo reloadRowsAtIndexPaths:withRowAnimation. È sufficiente implementare un metodo personalizzato reloadRowsWithMyAnimationAtIndexPaths: nella categoria di UITableView e utilizzarlo quando è necessario.

Ma se si desidera ignorare questo metodo in sottoclasse di UITableView, si potrebbe fare questo:

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths 
       withRowAnimation:(UITableViewRowAnimation)animation { 
    if (self.useMyAnimation) 
     [self reloadRowsWithMyAnimationAtIndexPaths:indexPaths]; 
    else 
     [super reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 
} 

self.useMyAnimation è solo una bandiera (proprietà BOOL) che indica ciò che l'animazione da utilizzare. Imposta questo flag prima di ricaricare l'operazione.

Per 2 o più customAnimations si potrebbe implementare enum:

enum MyTableViewReloadAnimationType { 
    case None 
    case First 
    case Second 
    case Third 
} 

poi fare una proprietà MyTableViewReloadAnimationType (ad esempio, reloadAnimationType) e selezionare un metodo di animazione appropriato con interruttore:

var reloadAnimationType = MyTableViewReloadAnimationType.None 

    override func reloadRowsAtIndexPaths(indexPaths: [AnyObject], withRowAnimation animation: UITableViewRowAnimation) { 
     switch self.reloadAnimationType { 
     case .None: 
      super .reloadRowsAtIndexPaths(indexPaths, withRowAnimation:animation) 
     default: 
      self .reloadRowsAtIndexPaths(indexPaths, withCustomAnimationType:self.reloadAnimationType) 
     } 
    } 

    func reloadRowsAtIndexPaths(indexPaths: [AnyObject], withCustomAnimationType animationType: MyTableViewReloadAnimationType) { 
     switch animationType { 
     case .First: 
      self .reloadRowsWithFirstAnimationAtIndexPaths(indexPaths) 
     case .Second: 
      self .reloadRowsWithSecondAnimationAtIndexPaths(indexPaths) 
     case .Third: 
      self .reloadRowsWithThirdAnimationAtIndexPaths(indexPaths) 
     } 
    } 

Si potrebbe chiama il metodo personalizzato reloadRowsAtIndexPaths:withCustomAnimationType: direttamente:

self.tableView .reloadRowsAtIndexPaths([indexPath], withCustomAnimationType: MyTableViewReloadAnimationType.First) 

All'interno del metodo personalizzato è necessario per ottenere una cella attuale e una nuova cella con il metodo di dataSource:

func reloadRowsWithFirstAnimationAtIndexPaths(indexPaths: [AnyObject]) { 
    for indexPath in indexPaths { 
     var currentCell = self .cellForRowAtIndexPath(indexPath as! NSIndexPath) 
     var newCell = self.dataSource .tableView(self, cellForRowAtIndexPath: indexPath as! NSIndexPath) 
     var newCellHeight = self.delegate .tableView(self, heightForRowAtIndexPath: indexPath) 
     var frame: CGRect = currentCell.frame 
     frame.size.height = newCellHeight 
     newCell.frame = frame 
     self .replaceCellWithFirstAnimation(currentCell!, withAnotherCell: newCell); 
    } 
} 

func replaceCellWithFirstAnimation(firstCell : UITableViewCell, withAnotherCell secondCell: UITableViewCell) { 
    var cellsSuperview = firstCell.superview! 
    //make this with animation 
    firstCell .removeFromSuperview() 
    cellsSuperview .addSubview(secondCell) 
} 

è necessario gestire una situazione in cui di newCell altezza> o < quindi l'altezza di CurrentCell. Tutti i fotogrammi di altre celle devono essere ricalcolati. Penso che potrebbe essere fatto con i metodi beginUpdates e endUpdates. Chiamali prima della manipolazione con le celle.

+0

Nessun problema per l'obiettivo C. Posso leggerlo, a patto che non debba scriverlo ... Per quanto riguarda "self.useMyAnimation' come lo si usa? Ho fatto lo stesso eccetto il fatto che il 'if' riguardava l'animazione 'essendo nullo o no in quanto non trovavo un altro modo. Ma è più un hack che una soluzione adeguata, se ho due animazioni personalizzate, non funziona. E come ricarichi la cella? – Nico

+0

Ho aggiornato la mia risposta per 2 o più animazioni personalizzate –

+0

Il problema è quando si chiama 'reloadRowsAtIndexPaths: withRowAnimation', si può solo specificare (correggimi se ho torto) il tipo di animazione con un' UITableViewRowAnimation'. E c'è solo una dichiarazione di 'reloadRowsAtIndexPaths: withRowAnimation'. Non mi dispiace non ignorare questo metodo e continuare a fare un metodo di ricarica personalizzato ma come ricaricare la cella? – Nico

Problemi correlati