-1

I want to be able to change to change the colours of a CAGradientLayer in realtime with values i receive over @IBAction in the main ViewController. UISlider moves, color changes in background. I m asking for a theoretical approach.

What is the pattern or technique used to achieve this ? i really got lost and the mighty internet didn't reveal any usable help.

  • Subclasssing a UIView and add the gradientLayer there ? Then observe the variable with the incoming values and let KVO update the array entries (color sets) with cgColor values ?

  • Instantiate the gradientLayer in the main ViewController and update its color Properties there when value changes come in via @IBAction ?

Code helps, but its secondary here. i am asking more for a theoretical solution. I try to follow MVC but i am hardly confused where the gradientLayer should be instantiated, whats the best method to change the colours dynamically ect… open for inputs, thx

cutcode
  • 3
  • 3

2 Answers2

0

Using a very simple extension for UIView you can get what you need. Here is a quick example using semi-static colors just for simplicity, but you can extend it as you need.

extension UIView {
    /**
     Adds colors to a CAGradient Layer.
     - Parameter value: The Float coming from the slider.
     - Parameter gradientLayer: The CAGradientLayer to change the colors.
     */
    func addColorGradient (value: CGFloat, gradientLayer: CAGradientLayer) {
        let topColor = UIColor(red: value / 255, green: 1, blue: 1, alpha: 1)
        let bottomColor = UIColor(red: 1, green: 1, blue: value / 255, alpha: 1)
        gradientLayer.colors = [topColor.cgColor, bottomColor.cgColor]
    }
}

Usage example:

import UIKit

class ViewController: UIViewController {

    let slider : UISlider = {
        let slider = UISlider(frame: .zero)
        slider.maximumValue = 255
        slider.minimumValue = 0.0
        return slider
    }()

    var gradientLayer = CAGradientLayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(slider)
        slider.translatesAutoresizingMaskIntoConstraints = false
        slider.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        slider.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        slider.widthAnchor.constraint(equalToConstant: 200).isActive = true
        slider.heightAnchor.constraint(equalToConstant: 20).isActive = true
        slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
        gradientLayer.bounds = self.view.bounds
        self.view.layer.insertSublayer(gradientLayer, at: 0)
    }

    @objc func sliderValueChanged(sender: UISlider) {
        let currentValue = CGFloat(sender.value)
        self.view.addColorGradient(value: currentValue, gradientLayer: gradientLayer)
    }

}

Just change the topColor and bottomColor as you need and manipulate their values with the slider. Hope it helps

Galo Torres Sevilla
  • 1,540
  • 2
  • 8
  • 15
  • That is the input i needed. Thank you @Galo Torres Sevilla. I use it with Swift 5 in Xcode 10.2 and it works as it should. I don't need all the slider stuff, because i am doing that via storyboard. – cutcode Mar 29 '19 at 15:59
0
class ViewController: UIViewController {

    var gradientLayer = CAGradientLayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        gradientLayer.bounds = self.view.bounds
        self.view.layer.insertSublayer(gradientLayer, at: 0)
    }

    // Slider Input
    @IBAction func sliderValueChanged(_ sender: UISlider) {
        self.view.addColorGradient(value: CGFloat(sender.value), gradientLayer: gradientLayer)
    }
}
cutcode
  • 3
  • 3
  • My `ViewController` after the answer from @Gallo Torres Sevilla. Works. I used the `UIView` extension without modifying. – cutcode Mar 29 '19 at 16:09