Core Animation makes it easy to repeat animations any number of times or for any duration. Sometimes, however, you may want to impose a delay duration after an animation finishes before it repeats. Core Animation doesn’t offer a direct API for such a feature, but it’s actually quite easy to set something like this up. This Quick Bits post will show a simple way to introduce a delay before repeating an animation.

Standard looping animation
Delayed looping animation

The simplest way to add a delay between animations is to use CAAnimationGroup. As its name implies, an animation group is a container object that groups together multiple animations and runs them concurrently. Importantly, it extends CAAnimation, so it’s actually an animation itself. Any animations added to CAAnimationGroup run relative to its time space. Therefore, to delay an animation between loops, simply increase the duration of the animation group beyond the duration of the animation it contains by a bit:

let animation = CABasicAnimation(keyPath: "position.x")
animation.toValue = 310.0
animation.duration = 1.0
animation.fillMode = kCAFillModeForwards
animation.autoreverses = true

let animationGroup = CAAnimationGroup()
animationGroup.animations = [animation]
animationGroup.duration = 3.0
animationGroup.repeatCount = .greatestFiniteMagnitude

layer.add(animationGroup, forKey: "groupAnimation")
Using an animation group to delay repeated animations

There are three important things to remember when using this approach:

  1. The animation needs to have its fill mode set to kCAFillModeForwards. This ensures the layer maintains the last frame of the animation after it finishes but before it loops again.
  2. The repeat count property that may have previously been set on the animation itself needs to instead be set on the animation group.1
  3. If your animation is supposed to autoreverse, the duration of the animation group needs to be at least twice that of the autoreversing animation.

That’s all it takes. Certainly there are other methods to wait before an animation repeats, but this is my preferred method because of its simplicity as well as its ability to expand to accommodate more complex animations within a single group.

Resources

  1. This is because the animation group is what is looping now, because it contains the additional time for the delay. The original animation should not loop. 

CALayer