Reputation: 1472
I'm trying to get a very basic CAGradientLayer
animation to work. I have a basic 2 color CAGradientLayer
set up and added to my UIViewController
.
// Set up the gradient layer.
var gradientLayer: CAGradientLayer! {
let layer = CAGradientLayer()
layer.frame = self.view.bounds
layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
layer.locations = [0.0, 1.0]
return layer
}
I am trying to animate it with the following code:
@IBAction func changeBackground(sender: AnyObject) {
let oldColors = self.gradientLayer.colors
let newColors = [UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor]
self.gradientLayer.colors = newColors
let animation: CABasicAnimation = CABasicAnimation(keyPath: "colors")
animation.fromValue = oldColors
animation.toValue = newColors
animation.duration = 0.3
animation.removedOnCompletion = true
animation.fillMode = kCAFillModeForwards
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.delegate = self
self.gradientLayer.addAnimation(animation, forKey: "animateGradientColorChange")
}
However, this code does not yield any change in the CAGradientLayer
. What am I doing wrong here ?
Upvotes: 3
Views: 981
Reputation: 8006
You are returning a new layer
object every time from your gradientLayer
property. You need to change it a bit, so that it is lazily initiated :
lazy var gradientLayer: CAGradientLayer! = {
let layer = CAGradientLayer()
layer.frame = self.view.bounds
layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
layer.locations = [0.0, 1.0]
return layer
}()
For completeness sake, what you had originally was a computed property, which meant that the code was executed each time you accessed it. With lazy properties, the code is executed only once, when the property is first accessed, and then the same object is returned.
The difference can be observed with this playground :
//: Playground - noun: a place where people can play
import UIKit
struct Dummy {
var gradientLayer: CAGradientLayer! {
let layer = CAGradientLayer()
layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
layer.locations = [0.0, 1.0]
return layer
}
lazy var lazyGradientLayer: CAGradientLayer! = {
let layer = CAGradientLayer()
layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
layer.locations = [0.0, 1.0]
return layer
}()
}
var dummy = Dummy()
let l1 = dummy.gradientLayer
let l2 = dummy.gradientLayer
let lazy1 = dummy.lazyGradientLayer
let lazy2 = dummy.lazyGradientLayer
Upvotes: 4