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() {
super.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)
animateLayer()
}
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.
fromColors
and toColors
global.animationDidStop
delegate method.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
animateLayer()
}
And you can also check working code here: Sample
For those in the comments asking about endless animations, here's my stock sample code for an endlessly animated background:-
The full discussion and results can be seen on my blog
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// create the gradient layer
let gradient = CAGradientLayer()
gradient.frame = self.view.bounds
gradient.startPoint = CGPoint(x:0.0, y:0.5)
gradient.endPoint = CGPoint(x:1.0, y:0.5)
gradient.colors = [UIColor.red.cgColor, UIColor.green.cgColor]
gradient.locations = [-0.5, 1.5]
let animation = CABasicAnimation(keyPath: "colors")
animation.fromValue = [UIColor.red.cgColor, UIColor.green.cgColor]
animation.toValue = [UIColor.green.cgColor, UIColor.red.cgColor]
animation.duration = 5.0
animation.autoreverses = true
animation.repeatCount = Float.infinity
// add the animation to the gradient
gradient.add(animation, forKey: nil)
// add the gradient to the view
self.view.layer.addSublayer(gradient)
}
}
For future reference... The 100% CPU usage is caused by the animationDidStop function. It restarts the animation while the current animations isn't finished. Please check the finished flag:
override func animationDidStop(anim: CAAnimation, finished: Bool) {
if finished {
self.toColors = self.fromColors;
self.fromColors = self.gradient?.colors
animateLayer()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With