web-dev-qa-db-fra.com

Durée de l'animation de ligne UITableView et rappel de fin

Existe-t-il un moyen de spécifier la durée des animations de ligne UITableView ou d'obtenir un rappel une fois l'animation terminée?

Ce que je voudrais faire, c'est faire clignoter les indicateurs de défilement une fois l'animation terminée. Faire le flash avant cela ne fait rien. Jusqu'à présent, la solution de contournement consiste à retarder d'une demi-seconde (ce qui semble être la durée d'animation par défaut), à savoir:

[self.tableView insertRowsAtIndexPaths:newRows
                      withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
                     withObject:nil
                     afterDelay:0.5];
95
Daniel Dickison

Je suis juste tombé sur cela. Voici comment procéder:

Objectif-C

[CATransaction begin];
[tableView beginUpdates];
[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
}];
[tableView insertRowsAtIndexPaths: indexPaths
                 withRowAnimation: UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[CATransaction commit];

rapide

CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock {
    // Code to be executed upon completion
}
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
tableView.endUpdates()
CATransaction.commit()
198
karwag

S'étendre sur la bonne réponse de karwag , notez que sur iOS 7, entourant la CATransaction avec une animation UIView offre un contrôle de la durée de l'animation de la table.

[UIView beginAnimations:@"myAnimationId" context:nil];

[UIView setAnimationDuration:10.0]; // Set duration here

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    NSLog(@"Complete!");
}];

[myTable beginUpdates];
// my table changes
[myTable endUpdates];

[CATransaction commit];
[UIView commitAnimations];

La durée de l'animation UIView n'a aucun effet sur iOS 6. Peut-être que les animations de table iOS 7 sont implémentées différemment, au niveau UIView.

39
Brent

Raccourcissement bonne réponse de Brent , pour au moins iOS 7, vous pouvez envelopper tout cela dans un appel [UIView animateWithDuration: delay: options: animations: complétion:] appel:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  [self.tableView beginUpdates];
  [self.tableView endUpdates];
} completion:^(BOOL finished) {
  // completion code
}];

cependant, je n'arrive pas à remplacer la courbe d'animation par défaut à partir d'autre chose que EaseInOut.

25
visnu

Voilà un enfer d'une astuce utile! J'ai écrit une extension UITableView pour éviter d'écrire des trucs CATransaction tout le temps.

import UIKit

extension UITableView {

    /// Perform a series of method calls that insert, delete, or select rows and sections of the table view.
    /// This is equivalent to a beginUpdates() / endUpdates() sequence, 
    /// with a completion closure when the animation is finished.
    /// Parameter update: the update operation to perform on the tableView.
    /// Parameter completion: the completion closure to be executed when the animation is completed.

    func performUpdate(_ update: ()->Void, completion: (()->Void)?) {

        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        // Table View update on row / section
        beginUpdates()
        update()
        endUpdates()

        CATransaction.commit()
    }

}

Ceci est utilisé comme ceci:

// Insert in the tableView the section we just added in sections
self.tableView.performUpdate({
            self.tableView.insertSections([newSectionIndex], with: UITableViewRowAnimation.top)

        }, completion: {
            // Scroll to next section
            let nextSectionIndexPath = IndexPath(row: 0, section: newSectionIndex)
            self.tableView.scrollToRow(at: nextSectionIndexPath, at: .top, animated: true)
        })
23
Frédéric Adda

Voici une Swift version de réponse de karwag

    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock { () -> Void in
        // your code here
    }
    tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
    tableView.endUpdates()
    CATransaction.commit()
23
primulaveris

Pour moi, j'avais besoin de cela pour une collectionView. J'ai fait une simple extension pour résoudre ce problème:

extension UICollectionView {

    func reloadSections(sections: NSIndexSet, completion: () -> Void){
        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        self.reloadSections(sections)

        CATransaction.commit()
    }

}
6
Antoine