DrPatience DrPatience - 8 months ago 71
Swift Question

Animate CAGradientLayer in Swift

I am attemping to animate the CAGradientLayer using Swift. For a resource I'm using this post

Here is my code

class ViewController: UIViewController {

var gradient : CAGradientLayer?;

override func viewDidLoad() {

override func viewDidAppear(animated: Bool) {

self.gradient = CAGradientLayer()
self.gradient?.frame = self.view.bounds
self.gradient?.colors = [ UIColor.redColor().CGColor, UIColor.redColor().CGColor]
self.view.layer.insertSublayer(self.gradient, atIndex: 0)


func animateLayer(){

var fromColors = self.gradient?.colors
var toColors: [AnyObject] = [ UIColor.blueColor().CGColor, UIColor.blueColor().CGColor]

var animation : CABasicAnimation = CABasicAnimation(keyPath: "colors")

animation.fromValue = fromColors
animation.toValue = toColors
animation.duration = 3.00
animation.removedOnCompletion = true
animation.fillMode = kCAFillModeForwards
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.delegate = self

self.gradient?.addAnimation(animation, forKey:"animateGradient")


I've attempted this in Objective-C and it works, but I need to use it in Swift and when I run the program it animates but goes back to the previous color at the end, I need it so remain blue.


I have checked your code and found one mistake here. You forgot to set color of self.gradient you are just giving colors to animation thats why animation is working fine and at the end you see its color goes back to red.

Write this missing code:

var toColors: [AnyObject] = [UIColor.blueColor().CGColor, UIColor.blueColor().CGColor]
self.gradient.colors = toColors // You missed this line
var animation : CABasicAnimation = CABasicAnimation(keyPath: "colors")

You can also check working code here: Sample

UPDATE: how do I repeat this gradient transition continuously ?

So you can use delegate of CAAnimation. It will let you know once the animation has been finished and then you can set the fromColors and toColors value and call the animateLayer() function again and again. But for this you will have to make few changes in your code.

  • Make fromColors and toColors global.
  • Change their value in animationDidStop delegate method.
  • Call the animateLayer() function again.

Here is the delegate method body:

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {

    self.toColors = self.fromColors;
    self.fromColors = self.gradient?.colors

And you can also check working code here: Sample