Create a continuously rotating square on the screen using animateKeyframesWithDuration

I faced same problem before, this is how I make it work:

Swift 2

let raw = UIViewKeyframeAnimationOptions.Repeat.rawValue | UIViewAnimationOptions.CurveLinear.rawValue
let options = UIViewKeyframeAnimationOptions(rawValue: raw)

Swift 3,4,5

let raw = UIView.KeyframeAnimationOptions.repeat.rawValue | UIView.AnimationOptions.curveLinear.rawValue
let options = UIView.KeyframeAnimationOptions(rawValue: raw)

I figured this problem out just before gave it up. I don't think there is doc about it, but it just work.


That's really odd... UIView.animateKeyframesWithDuration isn't working as I would expect it to with UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOpti‌​ons.Repeat passed in with options.

If you use the non-block method of creating a keyframe animation (see below) the rotation repeats as expected.

If I find out why the block-based option isn't working I'll try and remember to update answer here too!

override func viewDidLoad() {
    super.viewDidLoad()


    let square = UIView()
    square.frame = CGRect(x: 55, y: 300, width: 40, height: 40)
    square.backgroundColor = UIColor.redColor()
    self.view.addSubview(square)

    let fullRotation = CGFloat(M_PI * 2)

    let animation = CAKeyframeAnimation()
    animation.keyPath = "transform.rotation.z"
    animation.duration = 2
    animation.removedOnCompletion = false
    animation.fillMode = kCAFillModeForwards
    animation.repeatCount = Float.infinity
    animation.values = [fullRotation/4, fullRotation/2, fullRotation*3/4, fullRotation]

    square.layer.addAnimation(animation, forKey: "rotate")

}