Reputation: 79
I'm making a RGB slider programmatically and I've come across an issue where I can't seem to figure out how to properly show the color of each sliders' values as a UIColor. I've gotten as far as changing the colors in the box, but they come out grayscale and I don't understand why.
View class:
extension UIView {
func colorSlider(tintColor: UIColor) -> UISlider {
let slider = UISlider()
slider.minimumValue = 0
slider.maximumValue = 255
slider.isContinuous = true
slider.tintColor = tintColor
slider.frame.size = CGSize(width: 250, height: 20)
return slider
}
}
class SliderView: UIView {
let stackView: UIStackView
let redColorSlider = UIView().colorSlider(tintColor: .red)
let greenColorSlider = UIView().colorSlider(tintColor: .green)
let blueColorSlider = UIView().colorSlider(tintColor: .blue)
let previewColorButton: UIButton = {
let button = UIButton()
button.frame.size = CGSize(width: 80, height: 100)
return button
}()
override init(frame: CGRect) {
self.stackView = UIStackView(arrangedSubviews: [redColorSlider, greenColorSlider, blueColorSlider])
stackView.distribution = .fillEqually
stackView.spacing = 15
stackView.axis = .vertical
super.init(frame: frame)
setupLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setupLayout() {
backgroundColor = .white
addSubview(previewColorButton)
previewColorButton.anchor(left: leftAnchor, paddingLeft: 20, width: 80, height: 100)
previewColorButton.centerY(inView: self)
addSubview(stackView)
stackView.anchor(left: previewColorButton.rightAnchor, paddingLeft: 20, paddingRight: 20, width: 250)
stackView.centerY(inView: self)
}
}
Controller class:
class SliderController: UIViewController {
let sliderView = SliderView()
let step: Float = 0.1
let redLabel = UIView().rgbLabel()
var redValue: CGFloat = 0
let greenLabel = UIView().rgbLabel()
var greenValue: CGFloat = 0
let blueLabel = UIView().rgbLabel()
var blueValue: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
view = sliderView
redLabel.text = "0"
greenLabel.text = "0"
blueLabel.text = "0"
sliderView.previewColorButton.backgroundColor = .blue
sliderView.redColorSlider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .valueChanged)
sliderView.greenColorSlider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .valueChanged)
sliderView.blueColorSlider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .valueChanged)
sliderView.previewColorButton.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .valueChanged)
let stackView = UIStackView(arrangedSubviews: [redLabel, greenLabel, blueLabel])
stackView.distribution = .fillEqually
stackView.spacing = 5
view.addSubview(stackView)
stackView.anchor(bottom: view.safeAreaLayoutGuide.bottomAnchor)
stackView.centerX(inView: view)
}
@objc func sliderValueChanged(sender: UISlider) {
redValue = CGFloat(round(sender.value / step) * step)
greenValue = CGFloat(round(sender.value / step) * step)
blueValue = CGFloat(round(sender.value / step) * step)
redLabel.text = "\(Int(redValue))"
greenLabel.text = "\(Int(greenValue))"
blueLabel.text = "\(Int(blueValue))"
sliderView.previewColorButton.backgroundColor = UIColor(red: redValue/255, green: greenValue/255, blue: blueValue/255, alpha: 1.0)
}
I've tried separating the slider action function @objc func sliderValueChanged
to each individual slider action like so:
@objc func redSliderValueDidChange(sender: UISlider) {
let redSliderValue = round(sender.value / step) * step
redValue = CGFloat(redSliderValue)
redLabel.text = "\(Int(redValue))"
}
@objc func greenSliderValueDidChange(sender: UISlider) {
let greenSliderValue = round(sender.value / step) * step
greenValue = CGFloat(greenSliderValue)
greenLabel.text = "\(Int(greenValue))"
}
@objc func blueSliderValueDidChange(sender: UISlider) {
let blueSliderValue = round(sender.value / step) * step
blueValue = CGFloat(blueSliderValue)
blueLabel.text = "\(Int(blueValue))"
}
This helps so that each color label changes individually, as opposed to what I have above, but the colors don't change.
I haven't found any information on how to do this programmatically, so any help is appreciated!
Upvotes: 0
Views: 570
Reputation: 769
Please check the targets you have added to the slider.
Also, you can replace the following method in your code:
@objc func sliderValueChanged(sender: UISlider)
{
sliderView.previewColorButton.backgroundColor = UIColor(red: CGFloat(redSliderValue/255), green: CGFloat(greenSliderValue/255), blue: CGFloat(blueSliderValue/255), alpha: 1.0)
}
Upvotes: 1