How to update CAGradientLayer colors on runtime in iOS swift?

Viewed 4499

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)
    }
}
3 Answers

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()
    }
}
Related