Reputation: 5939
I am using a UIView extension for applying a gradient layer to a UIView. I need to change the gradient colors on runtime while scrolling a tableview. I use the scrollview contentoffset value to update the gradient color.
What I tried: I tried to remove the layer from superlayer and create a new gradientlayer with new colors. But app is getting memory issues and the UI is freezing sometimes.
Is it possible to update the CAGradientLayer gradient colors on runtime?
extension UIView {
func applyGradient(withColours colours: [UIColor], gradientOrientation orientation: GradientOrientation) {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colours.map { $0.cgColor }
gradient.startPoint = orientation.startPoint
gradient.endPoint = orientation.endPoint
self.layer.insertSublayer(gradient, at: 0)
}
}
Upvotes: 8
Views: 5587
Reputation: 499
An alternative solution would be to use an animation block to change the gradient colors...
extension CAGradientLayer
{
func animateChanges(to colors: [UIColor],
duration: TimeInterval)
{
CATransaction.begin()
CATransaction.setCompletionBlock({
// Set to final colors when animation ends
self.colors = colors.map{ $0.cgColor }
})
let animation = CABasicAnimation(keyPath: "colors")
animation.duration = duration
animation.toValue = colors.map{ $0.cgColor }
animation.fillMode = kCAFillModeForwards
animation.isRemovedOnCompletion = false
add(animation, forKey: "changeColors")
CATransaction.commit()
}
}
Upvotes: 2
Reputation: 5939
The answer to this question is to change the color property of the gradient layer from within the same scope. I tried doing this before, but from a different scope.Now it is working. The answer is given below.
Swift 3.1 code:
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 1)
view.layer.insertSublayer(gradient, at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
// this will be called after 10 seconds.
gradient.colors = [UIColor.red.cgColor, UIColor.black.cgColor]
}
Upvotes: 8
Reputation: 489
Try this one . Hope it helped..
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
view.layer.insertSublayer(gradient, at: 0)
Cheers
Upvotes: -1