Wie kann ich eine blockbasierte UIView-Animation abbrechen?

85

Ich habe viele SO-Sachen und in Apples Referenzen gesucht, kann mein Problem aber immer noch nicht lösen.

Was ich habe:

  1. Ein Bildschirm mit 2 UIImageViews und 2 UIButtons ist damit verbunden
  2. 2 Arten von Animationen:
    1. Skalieren Sie jedes Bild nacheinander nur einmal nach oben und unten viewDidLoad
    2. Wenn eine Taste gedrückt wird (eine benutzerdefinierte Schaltfläche, die in jedem von ihnen versteckt ist UIImageView), wird eine Animation von einer geeigneten - UIImageViewnur einer, nicht von beiden - ausgelöst (auch skalieren, dann verkleinern).
    3. Während ich für iOS4 + schreibe, wird mir gesagt, dass ich blockbasierte Animationen verwenden soll!

Was ich brauche:

Wie kann ich eine laufende Animation abbrechen? Ich habe es doch geschafft, bis auf den letzten abzubrechen ...: /

Hier ist mein Code-Snippet:

[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");
                                      }];
            }];
        }];
    }];

Irgendwie smallLetter UIImageViewfunktioniert das nicht richtig, weil beim Drücken (Durch-Taste) bigLetterAnimationen richtig abgebrochen werden ...

BEARBEITEN: Ich habe diese Lösung verwendet, habe aber immer noch Probleme mit der Verkleinerung smallLetter UIImageView- überhaupt nicht abbrechen ... Lösung

EDIT2: Ich habe dies am Anfang der next / prev-Methoden hinzugefügt:

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

Problem bleibt ...: / Keine Ahnung, wie die letzte Animation für Buchstaben in der Animationskette unterbrochen werden soll

Raistlin
quelle
Hey, ich denke Hari Kunwars Antwort sollte jetzt akzeptiert werden.
Marczellm
Heutzutage müssen Sie UIViewPropertyAnimator verwenden - es ist auch enorm einfacher.
Fattie

Antworten:

151

Sie können alle Animationen in einer Ansicht stoppen, indem Sie Folgendes aufrufen:

[view.layer removeAllAnimations];

(Sie müssen das QuartzCore-Framework importieren, um Methoden in view.layer aufzurufen.)

Wenn Sie eine bestimmte Animation stoppen möchten, nicht alle Animationen. Verwenden Sie CAAnimations am besten explizit anstelle der UIView-Animationshilfemethoden. Sie haben dann eine detailliertere Kontrolle und können Animationen explizit nach Namen stoppen.

Die Dokumentation zur Apple Core Animation finden Sie hier:

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

Nick Lockwood
quelle
10
Ich möchte nur hinzufügen, dass nach meiner eigenen Beobachtung die nachfolgende animateWithDuration nach dem Aufruf von removeAllAnimations nicht mehr funktioniert. Dies dient zum Paginieren und Ziehen, um die Steuerelemente zu aktualisieren. Vielleicht beobachtet jemand anderes etwas anderes. Am Ende verwende ich CABasicAnimation und rufe [myView.layer removeAnimationForKey: @ "animationKey"] auf.
Zhang
Vielen Dank für den Tipp @Nick - nur ein Hinweis darauf, dass der Link nicht mehr unterstützt zu werden scheint. Versuchen Sie stattdessen diesen: developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
trdavidson
52

Verwenden Sie für iOS 10 UIViewPropertyAnimator zum Animieren. Es bietet Methoden zum Starten, Stoppen und Anhalten von UIView-Animationen.

 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)
Hari Kunwar
quelle
3

Ich würde Nicks Antwort hinzufügen, dass es sehr praktisch ist, removeAllAnimations als nächste Idee reibungslos zu machen.

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

Sie können dies versuchen (in Swift):

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

Hinweis: Sie können bei Bedarf Code zwischen diese beiden Aufrufe einfügen, zum Beispiel:

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