120 votes

Comment faire pour détecter que l'animation s'est terminée sur UITableView beginUpdates/endUpdates?

Je suis l'insertion, la suppression d'une cellule de tableau à l'aide de insertRowsAtIndexPaths/deleteRowsAtIndexPaths enveloppé dans beginUpdates/endUpdates. Je suis également en utilisant beginUpdates/endUpdates lors du réglage de rowHeight. Toutes ces opérations sont animés par défaut.

Comment puis-je détecter que l'animation s'est terminée lors de l'utilisation d' beginUpdates/endUpdates?

297voto

Rudolf Adamkovic Points 4202

Quoi à ce sujet?

[CATransaction begin];

[CATransaction setCompletionBlock:^{
    // animation has finished
}];

[tableView beginUpdates];
// do some work
[tableView endUpdates];

[CATransaction commit];

Cela fonctionne parce que la tableView animations utilisation CALayer animations en interne. C'est, ajoutent-ils les animations pour tout ouvert CATransaction. Si aucune CATransaction existe (cas normal), alors on est implicitement a commencé, qui est terminé à la fin de l'actuel runloop. Mais si vous commencez à vous-même, comme cela est fait ici, alors il va l'utiliser.

5voto

Antoni Points 348

Une solution possible pourrait être d'hériter de la UITableView sur lequel vous appelez endUpdates et remplacer son setContentSizeMethod, depuis UITableView ajuste son contenu, de la taille de la ajouté ou supprimé des lignes. Cette approche devrait également fonctionner pour reloadData.

Pour s'assurer qu'une notification est envoyée seulement après l' endUpdates est appelé, on pourrait aussi remplacer endUpdates et de définir un indicateur.

// somewhere in header
@private BOOL endUpdatesWasCalled_;

-------------------

// in implementation file

- (void)endUpdates {
    [super endUpdates];
    endUpdatesWasCalled_ = YES;
}

- (void)setContentSize:(CGSize)contentSize {
    [super setContentSize:contentSize];

    if (endUpdatesWasCalled_) {
        [self notifyEndUpdatesFinished];
        endUpdatesWasCalled_ = NO;
    }
}

5voto

Zdenek Points 1441

Vous pouvez joindre votre opération(s) de UIView bloc d'animation de la sorte:

- (void)tableView:(UITableView *)tableView performOperation:(void(^)())operation completion:(void(^)(BOOL finished))completion
{
    [UIView animateWithDuration:0.0 animations:^{

        [tableView beginUpdates];
        if (operation)
            operation();
        [tableView endUpdates];

    } completion:^(BOOL finished) {

        if (completion)
            completion(finished);
    }];
}

Les crédits à http://stackoverflow.com/a/12905114/634940.

1voto

pixelfreak Points 7385

N'ai pas trouvé une bonne solution pour le moment (à court de sous-classement UITableView). J'ai décidé d'utiliser performSelector:withObject:afterDelay: pour l'instant. Pas l'idéal, mais fait le travail.

Mise à JOUR: Il semble que je peux utiliser scrollViewDidEndScrollingAnimation: (c'est spécifique à ma mise en œuvre, voir le commentaire).

0voto

chown Points 25161

Vous pouvez utiliser tableView:willDisplayCell:forRowAtIndexPath: comme:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"tableView willDisplay Cell");
    cell.backgroundColor = [UIColor colorWithWhite:((indexPath.row % 2) ? 0.25 : 0) alpha:0.70];
}

Mais ce sera aussi appelée lorsque une cellule qui se trouve déjà dans la table se déplace à partir de l'écran sur l'écran de sorte qu'il peut ne pas être exactement ce que vous cherchez. Je viens de regarder à travers toutes l' UITableView et UIScrollView délégué méthodes et il ne semble pas être quelque chose à gérer, juste après qu'une cellule est inséré animation.


Pourquoi ne pas simplement appeler la méthode que vous souhaitez être appelé lorsque l'animation se termine après l' endUpdates?

- (void)setDownloadedImage:(NSMutableDictionary *)d {
    NSIndexPath *indexPath = (NSIndexPath *)[d objectForKey:@"IndexPath"];
    [indexPathDelayed addObject:indexPath];
    if (!([table isDragging] || [table isDecelerating])) {
        [table beginUpdates];
        [table insertRowsAtIndexPaths:indexPathDelayed withRowAnimation:UITableViewRowAnimationFade];
        [table endUpdates];
        // --> Call Method Here <--
        loadingView.hidden = YES;
        [indexPathDelayed removeAllObjects];
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X