Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CAKeyframeAnimation delay before repeating

I have a CAKeyframeAnimation animation that I would like to repeat forever using repeatCount = HUGE_VALF. The animation's duration is 2 seconds, but I would like to have a 3 seconds pause before each cycle.

The only 2 ways I can think of doing that are:

  1. Make the whole animation last 5 seconds and add extra keyTimes and values so that I get the pause I'm looking for during the last 3s of the 5s animation. This feels kinda hacky.

  2. Have the animation only repeat once and then add use something like performSelector:afterDelay:2 to run the animation again, and so on and so on. This feels dirty as well. Also would mean that I need to call addAnimation: every 5 seconds, which I'm not sure is optimal in terms of performance.

Is there another option I might be missing? Is one of those 2 methods better than the other?

like image 972
samvermette Avatar asked Mar 03 '13 22:03

samvermette


2 Answers

By dumping the animations of Apple's MKUserLocationView, I was able to see how they were doing it. Turns out that this is what CAAnimationGroup is for. By encapsulating a 2 seconds animation into a 5 seconds animation group, you'll end up with a 2 seconds animation followed by a 3 seconds delay:

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = 5;
animationGroup.repeatCount = INFINITY;

CAMediaTimingFunction *easeOut = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
pulseAnimation.fromValue = @0.0;
pulseAnimation.toValue = @1.0;
pulseAnimation.duration = 2;
pulseAnimation.timingFunction = easeOut;

animationGroup.animations = @[pulseAnimation];

[ringImageView.layer addAnimation:animationGroup forKey:@"pulse"];
like image 77
samvermette Avatar answered Oct 10 '22 08:10

samvermette


samvermette's answer in Swift 3:

let animationGroup = CAAnimationGroup()
animationGroup.duration = 5;
animationGroup.repeatCount = .infinity

let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

let pulseAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
pulseAnimation.fromValue = 0
pulseAnimation.toValue = 1.0
pulseAnimation.duration = 2
pulseAnimation.timingFunction = easeOut

animationGroup.animations = [pulseAnimation]

ringImageView.layer.add(animationGroup, forKey: "pulse")
like image 40
Ivan Mir Avatar answered Oct 10 '22 08:10

Ivan Mir