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