Can animate CALayer's alpha but not backgroundColor

1k views Asked by At

I'd like to animate the background color of a layer. I am able to animate the alpha, but cannot animate the background color.

Works:

var animation = CABasicAnimation(keyPath: "opacity")
animation.toValue = 0.6
animation.duration = 0.1
customCALayer.addAnimation(animation, forKey: nil)

Does not work (no animation, no error):

var animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.redColor().CGColor
animation.toValue   = UIColor.whiteColor().CGColor
animation.duration = 0.1
customCALayer.addAnimation(animation, forKey: nil)

What's the deal? backgroundColor is an animatable property.

I have read several posts about this, and don't understand what I'm missing. The lack of feedback for a noop animation is challenging, I'm not sure where it's wrong. I've tried casting to AnyObject, using NSValue as a wrapper, and am not getting anywhere.

Related answers (that don't work for me):

1

There are 1 answers

0
clemens On

Your animation is basically correct, even if the Swift version is outdated in the meantime. With the current version it looks like this:

let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.toValue   = UIColor.white.cgColor
animation.duration = 0.1
customCALayer.add(animation, forKey: nil)

If the background color of your layer is not white, the layer will return to its original color after the animation. This can be avoided by making a small change:

customCALayer.backgroundColor = UIColor.white.cgColor // This step isn't necessary if the Layer is white already.
let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.duration = 0.1
customCALayer.add(animation, forKey: nil)

The animation changes the color from red to white and after the animation the layer remains white.

In many cases, implicit animations are sufficient for such cases:

CATransaction.begin()
CATransaction.setAnimationDuration(0.1)
customCALayer.backgroundColor = UIColor.white.cgColor
CATransaction.commit()

With the implicit animations you can also easily create several parallel animations. For example background color and opacity:

CATransaction.begin()
CATransaction.setAnimationDuration(0.1)
customCALayer.backgroundColor = UIColor.white.cgColor
customCALayer.opacity = 0.0
CATransaction.commit()