web-dev-qa-db-fra.com

Comment annuler une animation basée sur des blocs UIView?

J'ai effectué des recherches dans des charges de SO et dans les références d'Apple, mais je ne suis toujours pas parvenu à gérer mon problème.

Ce que j'ai:

  1. écran avec 2 UIImageViews nad connecté avec eux 2 boutons UIB
  2. 2 types d'animation:
    2.1. la première est en train d’agrandir, puis de descendre chaque image, l’une après l’autre, une seule fois dans viewDidLoad 2.2. le second, lorsque le bouton est enfoncé (bouton personnalisé, caché «à l'intérieur» de chaque UIImageView), il déclenche l'animation de UIImageView approprié - un seul, pas les deux - (également redimensionné, puis réduit).
  3. Pendant que j'écris pour iOS4 +, on me dit d'utiliser des animations par blocs!

Ce dont j'ai besoin:

Comment annuler une animation en cours? J'ai réussi à annuler après tout sauf la dernière ...: / Voici mon extrait de code:

[UIImageView animateWithDuration:2.0 
                               delay:0.1 
                             options:UIViewAnimationOptionAllowUserInteraction 
                          animations:^{
        isAnimating = YES;
        self.bigLetter.transform = CGAffineTransformScale(self.bigLetter.transform, 2.0, 2.0);
    } completion:^(BOOL finished){
        if(! finished) return;
        [UIImageView animateWithDuration:2.0 
                                   delay:0.0 
                                 options:UIViewAnimationOptionAllowUserInteraction 
                              animations:^{
            self.bigLetter.transform = CGAffineTransformScale(self.bigLetter.transform, 0.5, 0.5);
        } completion:^(BOOL finished){
            if(! finished) return;
            [UIImageView animateWithDuration:2.0 
                                       delay:0.0 
                                     options:UIViewAnimationOptionAllowUserInteraction 
                                  animations:^{
                self.smallLetter.transform = CGAffineTransformScale(self.smallLetter.transform, 2.0, 2.0);
            } completion:^(BOOL finished){
                if(! finished) return;
                [UIImageView animateWithDuration:2.0 
                                           delay:0.0 
                                         options:UIViewAnimationOptionAllowUserInteraction 
                                      animations:^{
                    self.smallLetter.transform = CGAffineTransformScale(self.smallLetter.transform, 0.5, 0.5);
                }
                                      completion:^(BOOL finished){
                                          if (!finished) return;
                                          //block letter buttons
                                          [self.bigLetterButton setUserInteractionEnabled:YES];
                                          [self.smallLetterButton setUserInteractionEnabled:YES];
                                          //NSLog(@"vieDidLoad animations finished");
                                      }];
            }];
        }];
    }];

D'une manière ou d'une autre, le smallLetter UIImageView ne fonctionne pas correctement, mais quand on appuie dessus (via le bouton), bigLetter annule correctement les animations ......... merci d'avance :)

EDIT: J'ai utilisé cette solution, mais j'ai toujours un problème avec la réduction de taille de smallLetter UIImageView - sans annuler du tout ... solution

EDIT2: J'ai ajouté ceci au début des méthodes next/prev:

- (void)stopAnimation:(UIImageView*)source {
    [UIView animateWithDuration:0.01
                          delay:0.0 
                        options:(UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction)
                     animations:^ {
                         source.transform = CGAffineTransformIdentity;
                     }
                     completion:NULL
     ];
}

le problème reste ...:/aucune idée de la façon d'interrompre la dernière animation pour les lettres dans la chaîne d'animation

69
raistlin

Vous pouvez arrêter toutes les animations d'une vue en appelant:

[view.layer removeAllAnimations];

(Vous devrez importer le framework QuartzCore pour appeler des méthodes sur view.layer).

Si vous souhaitez arrêter une animation spécifique, pas toutes les animations, votre meilleur choix est d'utiliser explicitement CAAnimations plutôt que les méthodes d'assistance d'animation UIView. Vous disposez ainsi d'un contrôle plus granulaire et pouvez arrêter les animations explicitement par leur nom.

La documentation Apple Core Animation est disponible ici:

https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html

136
Nick Lockwood

Pour iOS 10, utilisez UIViewPropertyAnimator pour animer. Il fournit des méthodes pour démarrer, arrêter et mettre en pause les animations UIView. 

 let animator = UIViewPropertyAnimator(duration: 2.0, curve: .easeOut){
        self.view.alpha = 0.0
 }
 // Call this to start animation.
 animator.startAnimation()

 // Call this to stop animation.
 animator.stopAnimation(true)
28
Hari Kunwar

J'ajouterais à la réponse de Nick que, pour supprimer toutes les animations, l'idée suivante serait très pratique.

[view.layer removeAllAnimations];
[UIView transitionWithView:self.redView
                  duration:1.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
                      [view.layer displayIfNeeded];
                  } completion:nil];
2
Gaston

Vous pouvez essayer ceci (dans Swift): 

UIView.setAnimationsEnabled(false)
UIView.setAnimationsEnabled(true)

Remarque: vous pouvez insérer du code entre ces deux appels si nécessaire, par exemple: 

UIView.setAnimationsEnabled(false)
aview.layer.removeAllAnimations() // remove layer based animations e.g. aview.layer.opacity
UIView.setAnimationsEnabled(true)
0
iAmcR