Search code examples
iosswiftanimationtimingcaanimation

Swift: consecutive CABasicAnimations that repeat


Goal:

  • First animation runs for a duration of 1.0
  • At 1.0, the second animation runs (while the first animation autoreverses back to its starting point)
  • At 2.0, the first animation is back at its starting point, the second animation has completed, and the first animation repeats
  • At 3.0, the second animation runs as the first animation concludes its second run

My code:

let animation = CABasicAnimation(keyPath: "transform.scale")
        animation.fromValue = 1.0
        animation.toValue = 1.5
        animation.duration = 1.0
        animation.autoreverses = true
        animation.repeatCount = .greatestFiniteMagnitude
        image1.layer.add(animation, forKey: animation.keyPath)

        let animation2 = CABasicAnimation(keyPath: "transform.scale")
        animation2.fromValue = 1.0
        animation2.toValue = 2.0
        animation2.duration = 1.0
        animation2.fillMode = .forwards

        let animation2b = CABasicAnimation(keyPath: "opacity")
        animation2b.fromValue = 1.0
        animation2b.toValue = 0.0
        animation2b.duration = 1.0
        animation2b.fillMode = .forwards

        let animationGroup = CAAnimationGroup()
        animationGroup.animations = [animation2, animation2b]
        animationGroup.duration = 2.0
        animationGroup.beginTime = 1.0
        animationGroup.repeatCount = .greatestFiniteMagnitude
        image2.layer.add(animationGroup, forKey: "scaleAndFade")

The goal is to start the 2nd animation 1.0 after the 1st animation. And since the animation group has a duration of 2.0 while the animations within it have a duration of only 1.0, the animation would start at 1.0, end at 2.0, and then not repeat again until 3.0

The two animations sometimes match up, but not on every build. Is there a more surefire way of starting the second animation to begin exactly at the end of the initial animation's first completed animation? So that they'll be in sync from that point on. Thanks for any help!


Solution

  • I like @matt's answer and always appreciate their input but since I was trying to use CAAnimation (specifically I wanted to use CAKeyframeAnimation), I ended up nesting two CATransactions using CATransaction.begin() and CATransaction.setCompletionBlock to start one animation exactly at the end of the other and then to recursively call the function repeatedly.

    CATransaction documentation