Annuler une animation UIView?

voix
221

Est - il possible d'annuler une UIViewanimation alors qu'il est en cours? Ou devrais - je laisser tomber au niveau de CA?

à-dire que je l'ai fait quelque chose comme ça (peut-être une mise en action d'animation de fin aussi):

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

// set view properties

[UIView commitAnimations];

Mais avant que l'animation complète et je reçois l'animation terminée événement, je veux l'annuler (couper court). Est-ce possible? Googler trouve autour de quelques personnes posent la même question sans réponse - et une ou deux personnes qui spéculent qu'il ne peut pas être fait.

Créé 17/02/2009 à 00:19
source utilisateur
Dans d'autres langues...                            


17 réponses

voix
342

Utilisation:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];
Créé 19/03/2010 à 07:53
source utilisateur

voix
111

La façon dont je le fais est de créer une nouvelle animation à votre point final. Définir une très courte durée et assurez-vous d' utiliser la +setAnimationBeginsFromCurrentState:méthode pour démarrer à partir de l'état actuel. Lorsque vous le réglez sur OUI, l'animation en cours est interrompue. On dirait quelque chose comme ceci:

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

// set view properties

[UIView commitAnimations];
Créé 08/05/2009 à 22:46
source utilisateur

voix
61

Simple moyen d'arrêter toutes les animations sur une vue particulière, immédiatement , est la suivante:

Lier le projet à QuartzCore.framework. Au début de votre code:

#import <QuartzCore/QuartzCore.h>

Maintenant, quand vous voulez arrêter toutes les animations sur une mort vue dans leurs voies, dire ceci:

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

La ligne médiane fonctionnerait tout seul, mais il y a un délai jusqu'à ce que les finitions runloop (le « redessiner moment »). Pour éviter ce délai, envelopper la commande dans un bloc de transaction explicite comme indiqué. Cela fonctionne à condition qu'aucune autre modification n'a été effectuée sur cette couche dans la runloop actuelle.

Créé 04/01/2012 à 00:03
source utilisateur

voix
43

Sur iOS 4 et plus, utilisez l' UIViewAnimationOptionBeginFromCurrentStateoption de sur la seconde animation pour couper la première animation courte.

À titre d'exemple, supposons que vous avez une vue avec un indicateur d'activité. Vous souhaitez effacer l'indicateur d'activité pendant une activité chronophage potentiellement commence et fade quand l'activité est terminée. Dans le code ci - dessous, la vue avec l'indicateur d'activité sur elle est appelée 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;
                     }
                 }];
}
Créé 11/08/2011 à 09:30
source utilisateur

voix
39

Pour annuler une animation il vous suffit de définir la propriété qui est en cours d'animation, en dehors de l'animation UIView. Qui arrêtera l'animation là où elle est, et le UIView sauteront au réglage que vous venez de définir.

Créé 19/06/2010 à 18:09
source utilisateur

voix
9

Si vous animez une contrainte en changeant la constante au lieu d'un pas de propriétés de vue des autres méthodes de travail sur iOS 8.

Exemple d'animation:

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) {

                 }];

Solution:

Vous devez supprimer les animations des couches de toutes les vues sont affectées par le changement de contrainte et de leurs sous-couches.

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}
Créé 07/11/2014 à 17:21
source utilisateur

voix
8

Désolé de ressusciter cette réponse, mais dans iOS 10 choses un peu changé, et maintenant l'annulation est possible et vous pouvez même annuler grâce!

Après iOS 10 , vous pouvez annuler les animations avec UIViewPropertyAnimator !

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

Si vous passez vrai, il annule l'animation et il arrête là où vous l'avez annulée. La méthode d'achèvement ne sera pas appelé. Cependant, si vous passez faux, vous êtes responsable de l'animation de finition:

animator.finishAnimation(.start)

Vous pouvez terminer votre animation et de rester dans l'état actuel (.current) ou allez à l'état initial (.start) ou à l'état final (.end)

Soit dit en passant, vous pouvez même faire une pause et redémarrer plus tard ...

animator.pauseAnimation()
animator.startAnimation()

Remarque: Si vous ne voulez pas une brusque annulation vous pouvez inverser votre animation ou même changer votre animation après vous mettre en pause!

Créé 09/11/2017 à 17:57
source utilisateur

voix
7

Si vous voulez juste faire une pause / arrêt animation en douceur

self.yourView.layer.speed = 0;

Source: Comment faire pour mettre en pause l'animation d'un arbre de couche

Créé 29/06/2015 à 11:02
source utilisateur

voix
5
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
Créé 06/02/2015 à 05:30
source utilisateur

voix
5

Aucune de ces résolu pour moi, mais cela a contribué: L' UIViewanimation définit la propriété immédiatement, puis l' anime. Il arrête l'animation lorsque la couche de présentation correspond au modèle (la propriété set).

Je résolu mon problème, ce qui était « Je veux animer d'où vous regardez comme vous semblez » (ce qui signifie « vous » le point de vue). Si vous voulez que, alors:

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

régler la position de la couche de présentation

J'utilise quelques options, y compris UIViewAnimationOptionOverrideInheritedDuration

Mais parce que la documentation d'Apple est vague, je ne sais pas si elle remplace vraiment les autres animations quand il est utilisé, ou remet à zéro juste minuteries.

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

Et cela devrait être une solution décente pour l'instant.

Créé 16/08/2011 à 18:21
source utilisateur

voix
1

J'ai le même problème; les API n'ont rien d'annuler une animation spécifique. le

+ (void)setAnimationsEnabled:(BOOL)enabled

désactive toutes les animations, et donc ne fonctionne pas pour moi. Il y a deux solutions:

1) faire votre animation objet d'une sous-vue. Ensuite, lorsque vous voulez annuler les animations pour ce point de vue, retirez la vue ou le cacher. Très simple, mais vous devez recréer la sous-vue sans animations si vous avez besoin de le garder en vue.

2) répéter l'anim seul, et faire un sélecteur de délégué pour redémarrer l'anim si nécessaire, comme ceci:

-(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];
}
}

Problème 2) est qu'il ya toujours retarder l'arrêt de l'anim comme il se termine le cycle d'animation en cours.

J'espère que cela t'aides.

Créé 08/05/2009 à 18:03
source utilisateur

voix
0

Aucune des solutions répondues a fonctionné pour moi. Je résolu mes problèmes de cette façon (je ne sais pas si elle est une bonne façon?), Parce que j'avais des problèmes lors de l' appel de cette trop rapide (lorsque l' animation précédente était pas encore fini). Je passe mon voulu animation avec customAnim bloc.

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()
                }
        })

    }

}
Créé 20/08/2019 à 14:52
source utilisateur

voix
0

Quand je travaille avec UIStackViewanimation, en plus removeAllAnimations()je dois fixer des valeurs initiales parce que l' un removeAllAnimations()peut les mettre à l' état imprévisible. J'ai stackViewavec view1et à l' view2intérieur, et un point de vue doit être visible et un caché:

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)
}
Créé 07/02/2019 à 09:03
source utilisateur

voix
0

Version rapide de la solution de Stephen Darlington

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

// set view properties
UIView.commitAnimations()
Créé 26/12/2017 à 15:09
source utilisateur

voix
0

Pour mettre en pause une animation sans revenir à l'état initial ou final:

CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
myView.layer.speed = 0.0;
myView.layer.timeOffset = paused_time;
Créé 03/12/2015 à 21:43
source utilisateur

voix
0
CALayer * pLayer = self.layer.presentationLayer;
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView animateWithDuration:0.001 animations:^{
    self.frame = pLayer.frame;
}];
Créé 28/01/2013 à 15:54
source utilisateur

voix
0

Même si vous annulez l'animation de la manière ci - dessus animation didStopSelectorfonctionne toujours. Donc , si vous avez des états logiques dans votre application tirée par des animations vous aurez des problèmes. Pour cette raison , les moyens décrits ci - dessus , j'utilise la variable de contexte UIViewanimations. Si vous passez l'état actuel de votre programme par le contexte param à l'animation, lorsque l'animation se fige votre didStopSelectorfonction peut décider si elle doit faire quelque chose ou tout simplement revenir en fonction de l'état actuel et la valeur d'état passé en contexte.

Créé 05/10/2010 à 09:52
source utilisateur

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