Annulla un'animazione UIView?

voti
221

E 'possibile annullare un UIViewun'animazione mentre è in corso? Oppure avrei dovuto scendere a livello di CA?

vale a dire che ho fatto qualcosa di simile (forse impostando un'azione di animazione fine troppo):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

Ma prima che l'animazione completa e ottengo l'animazione è conclusa manifestazione, voglio cancellarlo (tagliare corto). È possibile? Googling intorno trova poche persone che chiedono la stessa domanda senza risposte - e una o due persone che speculano che non può essere fatto.

È pubblicato 17/02/2009 alle 00:19
fonte dall'utente
In altre lingue...                            


17 risposte

voti
342

Uso:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
Risposto il 19/03/2010 a 07:53
fonte dall'utente

voti
111

Il modo in cui lo faccio è quello di creare una nuova animazione al punto finale. Impostare una durata molto breve e assicurarsi di utilizzare il +setAnimationBeginsFromCurrentState:metodo per iniziare dallo stato attuale. Quando si imposta su SI, l'animazione corrente viene tagliato corto. Sembra qualcosa di simile a questo:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];
Risposto il 08/05/2009 a 22:46
fonte dall'utente

voti
61

Modo più semplice per fermare tutte le animazioni in una vista particolare, immediatamente , è la seguente:

Collegare il progetto ad QuartzCore.framework. All'inizio del codice:

#import <QuartzCore/QuartzCore.h>

Ora, quando si desidera interrompere tutte le animazioni in un vicolo vista nella loro tracce, dire questo:

[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];

La linea mediana dovrebbe funzionare da sola, ma c'è un ritardo fino al termine runloop (il "ridisegnare momento"). Per evitare questo ritardo, avvolgere il comando in un blocco di transazione esplicita, come mostrato. Questo opere previste altre modifiche sono state eseguite su questo livello nel runloop corrente.

Risposto il 04/01/2012 a 00:03
fonte dall'utente

voti
43

Su iOS 4 e maggiore, utilizzare l' UIViewAnimationOptionBeginFromCurrentStateopzione sulla seconda animazione per tagliare la prima animazione breve.

A titolo di esempio, si supponga di avere una vista con un indicatore di attività. Si vuole svanire nel indicatore di attività, mentre alcuni potenzialmente tempo attività inizia, e dissolvenza fuori quando l'attività è terminata. Nel seguente codice, la vista con l'indicatore di attività sul si chiama activityView.

- (void)showActivityIndicator {
    activityView.alpha = 0.0;
    activityView.hidden = NO;
    [UIView animateWithDuration:0.5
                 animations:^(void) {
                     activityView.alpha = 1.0;
                 }];

- (void)hideActivityIndicator {
    [UIView animateWithDuration:0.5
                 delay:0 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^(void) {
                     activityView.alpha = 0.0;
                 }
                 completion:^(BOOL completed) {
                     if (completed) {
                         activityView.hidden = YES;
                     }
                 }];
}
Risposto il 11/08/2011 a 09:30
fonte dall'utente

voti
39

Per annullare un'animazione è sufficiente impostare la proprietà che è attualmente in corso di animazione, al di fuori dell'animazione UIView. Che fermerà l'animazione dovunque sia, e l'UIView salterà l'impostazione appena definito.

Risposto il 19/06/2010 a 18:09
fonte dall'utente

voti
9

Se si sta animando un vincolo cambiando la costante invece di una finestra delle proprietà nessuno degli altri metodi di lavorare su iOS 8.

Esempio di animazione:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

Soluzione:

È necessario rimuovere le animazioni dagli strati di eventuali pareri di essere interessata dalla modifica vincolo e le loro sottolivelli.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}
Risposto il 07/11/2014 a 17:21
fonte dall'utente

voti
8

Siamo spiacenti di far risorgere questa risposta, ma in iOS 10 cose po 'cambiato, e ora l'annullamento è possibile e si può anche cancellare la grazia!

Dopo iOS 10 è possibile annullare le animazioni con UIViewPropertyAnimator !

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

Se si passa vero annulla l'animazione e si ferma proprio dove è stata annullata esso. Il metodo di completamento non sarà chiamato. Tuttavia, se si passa falso di essere responsabile per la finitura l'animazione:

animator.finishAnimation(.start)

Si può terminare l'animazione e rimanere allo stato attuale (.Current) o andare allo stato iniziale (.start) o lo stato finale (.end)

Tra l'altro, si può anche mettere in pausa e riavviare più tardi ...

animator.pauseAnimation()
animator.startAnimation()

Nota: Se non si desidera che un brusco annullamento si può invertire l'animazione o anche cambiare l'animazione dopo aver sospeso esso!

Risposto il 09/11/2017 a 17:57
fonte dall'utente

voti
7

Se si desidera solo per mettere in pausa / stop di animazione senza intoppi

self.yourView.layer.speed = 0;

Fonte: Come mettere in pausa l'animazione di un albero strato di

Risposto il 29/06/2015 a 11:02
fonte dall'utente

voti
5
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
Risposto il 06/02/2015 a 05:30
fonte dall'utente

voti
5

Nessuno dei precedenti risolto per me, ma questo ha aiutato: L' UIViewanimazione imposta immediatamente la proprietà, poi lo anima. Si ferma l'animazione quando il livello di presentazione corrisponde al modello (la proprietà impostata).

Ho risolto il mio problema, che è stato "Voglio animare da dove si guarda come appari" ( 'si' che significa la vista). Se si desidera che questo, allora:

  1. Aggiungere QuartzCore.
  2. CALayer * pLayer = theView.layer.presentationLayer;

impostare la posizione del livello di presentazione

Io uso un paio di opzioni, tra cui UIViewAnimationOptionOverrideInheritedDuration

Ma poiché la documentazione di Apple è vago, non so se prevale davvero le altre animazioni quando viene utilizzato, o semplicemente azzera timer.

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

E che dovrebbe essere una soluzione decente per ora.

Risposto il 16/08/2011 a 18:21
fonte dall'utente

voti
1

Ho lo stesso problema; le API non hanno nulla di annullare qualche animazione specifica. Il

+ (void)setAnimationsEnabled:(BOOL)enabled

disabilita tutte le animazioni, e quindi non funziona per me. Ci sono due soluzioni:

1) rendere il vostro animata oggetto una visualizzazione secondaria. Poi, quando si desidera annullare le animazioni per quella vista, rimuovere la vista o nasconderlo. Molto semplice, ma è necessario ricreare la visualizzazione secondaria senza animazioni se è necessario tenerlo in vista.

2) ripetere l'anim sola, e fare un selettore delegato per riavviare l'Anim, se necessario, in questo modo:

-(void) startAnimation {
NSLog(@"startAnim alpha:%f", self.alpha);
[self setAlpha:1.0];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(pulseAnimationDidStop:finished:context:)];
[self setAlpha:0.1];
[UIView commitAnimations];
}

- (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if(hasFocus) {
    [self startAnimation];
} else {
    self.alpha = 1.0;
}
}

-(void) setHasFocus:(BOOL)_hasFocus {
hasFocus = _hasFocus;
if(hasFocus) {
    [self startAnimation];
}
}

Problemi con 2) è che c'è sempre ritardo di stop Anim come termina il ciclo di animazione corrente.

Spero che questo ti aiuti.

Risposto il 08/05/2009 a 18:03
fonte dall'utente

voti
0

Nessuna delle soluzioni risposto ha lavorato per me. Ho risolto i miei problemi in questo modo (non so se è un modo corretto?), Perché ho avuto problemi quando si chiama questo troppo veloce (quando l'animazione precedente non era ancora finito). Io passo la mia animazione voluto con customAnim blocco.

extension UIView
{

    func niceCustomTranstion(
        duration: CGFloat = 0.3,
        options: UIView.AnimationOptions = .transitionCrossDissolve,
        customAnim: @escaping () -> Void
        )
    {
        UIView.transition(
            with: self,
            duration: TimeInterval(duration),
            options: options,
            animations: {
                customAnim()
        },
            completion: { (finished) in
                if !finished
                {
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    self.layer.removeAllAnimations()
                    customAnim()
                }
        })

    }

}
Risposto il 20/08/2019 a 14:52
fonte dall'utente

voti
0

Quando lavoro con UIStackViewl'animazione, oltre che removeAllAnimations()ho bisogno di impostare alcuni valori di siglare uno perché removeAllAnimations()li può impostare a stato imprevedibile. Ho stackViewcon view1e view2dentro, e un punto di vista deve essere visibile e una nascosta:

public func configureStackView(hideView1: Bool, hideView2: Bool) {
    let oldHideView1 = view1.isHidden
    let oldHideView2 = view2.isHidden
    view1.layer.removeAllAnimations()
    view2.layer.removeAllAnimations()
    view.layer.removeAllAnimations()
    stackView.layer.removeAllAnimations()
    // after stopping animation the values are unpredictable, so set values to old
    view1.isHidden = oldHideView1 //    <- Solution is here
    view2.isHidden = oldHideView2 //    <- Solution is here

    UIView.animate(withDuration: 0.3,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                    view1.isHidden = hideView1
                    view2.isHidden = hideView2
                    stackView.layoutIfNeeded()
    },
                   completion: nil)
}
Risposto il 07/02/2019 a 09:03
fonte dall'utente

voti
0

Versione Swift della soluzione di Stephen Darlington

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()
Risposto il 26/12/2017 a 15:09
fonte dall'utente

voti
0

Per mettere in pausa un'animazione senza ritornare alla condizione originale o finale:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
Risposto il 03/12/2015 a 21:43
fonte dall'utente

voti
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
Risposto il 28/01/2013 a 15:54
fonte dall'utente

voti
0

Anche se si annulla l'animazione nei modi di cui sopra animazione didStopSelectorcorre ancora. Quindi, se avete stati logici nell'applicazione guidato da animazioni si avranno problemi. Per questo motivo, con le modalità sopra descritte uso la variabile di contesto di UIViewanimazioni. Se si passa lo stato attuale del vostro programma dal contesto param per l'animazione, quando l'animazione si ferma la vostra didStopSelectorfunzione può decidere se si dovrebbe fare qualcosa o semplicemente tornare sulla base dello stato attuale e il valore dello stato passato come contesto.

Risposto il 05/10/2010 a 09:52
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more