web-dev-qa-db-fra.com

Comment faire répéter et inverser automatiquement la séquence d'animation UIView

Comment faire répéter et inverser automatiquement cette animation complexe? Existe-t-il un moyen d'ajouter des options UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRépéter cette séquence d'animation?

   [UIView animateWithDuration:1.0f animations:^{

        someView.frame = someFrame1;

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.5f animations:^{

            someView.frame = someFrame2;

        } completion:nil];

    }];
35
B.S.

Pour animer du point 1 à 2 à 3 à 2 à 1 et répéter, vous pouvez utiliser animateKeyframesWithDuration dans iOS 7 et versions ultérieures:

someView.frame = frame1;
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat animations:^{
    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        someView.frame = frame2;
    }];
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        someView.frame = frame3;
    }];
} completion:nil];

Si vous utilisez la mise en page automatique, vous pouvez animer la modification des constantes de contrainte:

[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat animations:^{
    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        topConstraint.constant = 200;
        leftConstraint.constant = 200;
        [self.view layoutIfNeeded];
    }];
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        topConstraint.constant = 100;
        leftConstraint.constant = 300;
        [self.view layoutIfNeeded];
    }];
} completion:nil];

Ou bien, l'approche avec la mise en page automatique consiste à désactiver les contraintes, puis vous pouvez animer en utilisant les valeurs frame ou ce que vous avez.


Dans les versions antérieures d'iOS, vous pouvez utiliser CAKeyframeAnimation, par exemple pour animer le long d'un chemin:

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(100.0, 100.0)];
[path addLineToPoint:CGPointMake(200.0, 200.0)];
[path addLineToPoint:CGPointMake(100.0, 300.0)];

CAKeyframeAnimation *animatePosition = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animatePosition.path = [path CGPath];
animatePosition.duration = 1.0;
animatePosition.autoreverses = YES;
animatePosition.repeatCount = HUGE_VALF;
[self.someView.layer addAnimation:animatePosition forKey:@"position"];

Vous pouvez le faire avec autant de points que vous le souhaitez. Cette technique est également utile si vous souhaitez animer le long d'un chemin incurvé (par exemple, un cercle ou une courbe de Bézier).


Pour animer simplement entre deux points, vous pouvez utiliser animateWithDuration:delay:options:animations:completion:, tel que:

[UIView animateWithDuration:0.5
                      delay:0.0
                    options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     // do whatever animation you want, e.g.,

                     someView.frame = someFrame1;
                 }
                 completion:NULL];

Cela anime le mouvement de someView de l'image de départ vers someFrame1 et retour.

Soit dit en passant, l'utilisation de UIViewAnimationOptionCurveEaseInOut conjointement avec UIViewAnimationOptionAutoreverse et UIViewAnimationOptionRepeat vous donnera un effet plus fluide lorsque l'animation s'inverse et se répète.

109
Rob

Swift 4 pour une séquence de mouvement simple:

func animateWiggle() {
    // Set animation props
    let scaleDelta = CGFloat(0.10)

    // Set transforms
    let wiggleOutHorizontally = CGAffineTransform(scaleX: 1.0 + scaleDelta, y: 1.0)
    let wiggleOutVertically = CGAffineTransform(scaleX: 1.0, y: 1.0 + scaleDelta)

    // Run animation sequence
    UIView.animateKeyframes(withDuration: 1.0, delay: 0.0, options: [.autoreverse, .repeat], animations: {
        // Animate wiggle horizontally
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: {
            self.transform = wiggleOutHorizontally
        })

        // Animate wiggle vertically
        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
            self.transform = wiggleOutVertically
        })
    },
    completion: nil)
}
4
Crashalot