Come annullare l'animazione basata su blocchi UIView?


86

Ho cercato un sacco di cose SO e nei riferimenti di Apple, ma non sono ancora in grado di gestire il mio problema.

Ciò che ho:

  1. Uno schermo con 2 se UIImageView2 UIButtons ad essi collegati
  2. 2 tipi di animazione:
    1. Ridimensionamento verso l'alto e poi verso il basso di ogni immagine, uno dopo l'altro, solo una volta viewDidLoad
    2. Quando si preme un pulsante (un pulsante personalizzato nascosto "all'interno" di ciascuno UIImageView), si attiva l'animazione dell'appropriato ( UIImageViewsolo uno, non entrambi) (anche in scala verso l'alto, poi verso il basso).
    3. Mentre scrivo per iOS4 + mi è stato detto di usare animazioni basate su blocchi!

Ciò che di cui ho bisogno:

Come si annulla un'animazione in esecuzione? Sono riuscito a cancellarmi dopo tutto tranne l'ultimo ...: /

Ecco il mio frammento di codice:

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

In qualche modo il smallLetter UIImageViewnon funziona correttamente, perché quando viene premuto (tramite il pulsante) bigLetterannulla correttamente le animazioni ...

EDIT: ho usato questa soluzione, ma ho ancora problemi con il ridimensionamento smallLetter UIImageView- non annullando affatto ... soluzione

EDIT2: l' ho aggiunto all'inizio dei metodi next / prev:

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

il problema rimane ...: / non ho idea di come interrompere l'ultima animazione per le lettere nella catena dell'animazione


Ehi, penso che la risposta di Hari Kunwar dovrebbe essere accettata ora.
marczellm

In questi giorni è necessario utilizzare UIViewPropertyAnimator: è anche tremendamente più facile.
Fattie

Risposte:


151

Puoi interrompere tutte le animazioni su una vista chiamando:

[view.layer removeAllAnimations];

(Dovrai importare il framework QuartzCore per chiamare i metodi su view.layer).

Se desideri interrompere un'animazione specifica, non tutte le animazioni, la soluzione migliore è utilizzare CAAnimations in modo esplicito anziché i metodi di supporto dell'animazione UIView, quindi avrai un controllo più granulare e potrai interrompere le animazioni esplicitamente per nome.

La documentazione di Apple Core Animation può essere trovata qui:

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


10
Voglio solo aggiungere, nella mia osservazione, il successivo animateWithDuration non funziona più dopo aver chiamato removeAllAnimations. Questo serve per eseguire l'impaginazione e il pull per aggiornare i controlli, forse qualcun altro potrebbe osservare qualcosa di diverso. Finisco per usare CABasicAnimation e chiamare [myView.layer removeAnimationForKey: @ "animationKey"];
Zhang

Grazie per il suggerimento @Nick - solo un avvertimento che il collegamento non sembra più essere supportato, prova questo invece: developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
trdavidson

dopo view.layer.removeAllAnimations () aggiungi di nuovo la vista animata non funzionante
Bunthoeun

52

Per iOS 10 usa UIViewPropertyAnimator per animare. Fornisce metodi per avviare, interrompere e sospendere le animazioni 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)

3

Aggiungerei alla risposta di Nick che per rendere removeAllAnimations liscia l'idea successiva sia molto utile.

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

0

Puoi provare questo (in Swift):

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

Nota: puoi inserire del codice tra queste due chiamate se necessario, ad esempio:

UIView.setAnimationsEnabled(false)
aview.layer.removeAllAnimations() // remove layer based animations e.g. aview.layer.opacity
UIView.setAnimationsEnabled(true)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.