I am trying to implement the class HSBColorPicker in my app. I have everything compiling and running like I want up to this point but where I am stuck is trying to get the color information from the HSBColorPicker class and use it in my other classes. Here is what my app looks like right now:
My goal is that the user touches anywhere on the color spectrum at the top and that color is picked and is set to the current color. The code for the color picker works, as does the code for my view controller. Basically what I cannot figure out is how to retrieve the UIColor that the user has selected by tapping on the spectrum. More specifically I need to extract the Red, Green, and Blue values from that UIColor.
Once I have those values I can take it from there but I am stumped as to how to get the UIColor from the HSBColorPicker class in my ColorsViewController class.
Here is the HSBColorPicker class:
//
// HSBColorPicker.swift
// LED Ring App
//
// Created by Blake Fabiani on 9/22/16.
// Copyright © 2016 Blake Fabiani. All rights reserved.
//
import UIKit
internal protocol HSBColorPickerDelegate : NSObjectProtocol {
func HSBColorColorPickerTouched(sender:HSBColorPicker, color:UIColor, point:CGPoint, state:UIGestureRecognizerState)
}
@IBDesignable
class HSBColorPicker : UIView {
weak internal var delegate: HSBColorPickerDelegate?
let saturationExponentTop:Float = 2.0
let saturationExponentBottom:Float = 1.3
@IBInspectable var elementSize: CGFloat = 1.0 {
didSet {
setNeedsDisplay()
}
}
private func initialize() {
self.clipsToBounds = true
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(HSBColorPicker.touchedColor(_:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
for y in stride(from: 0, to: rect.height, by: elementSize) {
var saturation = y < rect.height / 2.0 ? CGFloat(2 * y) / rect.height : 2.0 * CGFloat(rect.height - y) / rect.height
saturation = CGFloat(powf(Float(saturation), y < rect.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = y < rect.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect.height - y) / rect.height
for x in stride(from: 0, to: rect.width, by: elementSize) {
let hue = x / rect.width
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y:y, width:elementSize,height:elementSize))
}
}
}
func getColorAtPoint(point:CGPoint) -> UIColor {
let roundedPoint = CGPoint(x:elementSize * CGFloat(Int(point.x / elementSize)),
y:elementSize * CGFloat(Int(point.y / elementSize)))
var saturation = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(2 * roundedPoint.y) / self.bounds.height
: 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
saturation = CGFloat(powf(Float(saturation), roundedPoint.y < self.bounds.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
let hue = roundedPoint.x / self.bounds.width
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
}
func getPointForColor(color:UIColor) -> CGPoint {
var hue:CGFloat=0;
var saturation:CGFloat=0;
var brightness:CGFloat=0;
color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil);
var yPos:CGFloat = 0
let halfHeight = (self.bounds.height / 2)
if (brightness >= 0.99) {
let percentageY = powf(Float(saturation), 1.0 / saturationExponentTop)
yPos = CGFloat(percentageY) * halfHeight
} else {
//use brightness to get Y
yPos = halfHeight + halfHeight * (1.0 - brightness)
}
let xPos = hue * self.bounds.width
return CGPoint(x: xPos, y: yPos)
}
func touchedColor(_ gestureRecognizer: UILongPressGestureRecognizer){
let point = gestureRecognizer.location(in: self)
let color = getColorAtPoint(point: point)
self.delegate?.HSBColorColorPickerTouched(sender: self, color: color, point: point, state:gestureRecognizer.state)
}
}
And Here is the ColorsViewController
//
// ColorsViewController.swift
// LED Ring App
//
// Created by Blake Fabiani on 9/13/16.
// Copyright © 2016 Blake Fabiani. All rights reserved.
//
import UIKit
var redColor: float_t = 0
var greenColor: float_t = 0
var blueColor: float_t = 0
class ColorsViewController: UIViewController {
@IBOutlet weak var redSlider: UISlider!
@IBOutlet weak var greenSlider: UISlider!
@IBOutlet weak var blueSlider: UISlider!
@IBOutlet weak var ColorPickerImageView: UIImageView!
@IBOutlet weak var redColorLabel: UILabel!
@IBOutlet weak var greenColorLabel: UILabel!
@IBOutlet weak var blueColorLabel: UILabel!
@IBOutlet weak var currentColorButton: UIButton!
@IBAction func redSliderAction(_ sender: UISlider) {
changeColors()
}
@IBAction func greenSliderAction(_ sender: UISlider) {
changeColors()
}
@IBAction func blueSliderAction(_ sender: UISlider) {
changeColors()
}
func chageCurrentColorImage() {
currentColorButton.backgroundColor = UIColor(red: CGFloat(redColor/Float(255.0)), green: CGFloat(greenColor/Float(255)), blue: CGFloat(blueColor/Float(255)), alpha: 1.0)
changeSliderLabel()
}
func changeColors() {
redColor = redSlider.value
greenColor = greenSlider.value
blueColor = blueSlider.value
chageCurrentColorImage()
}
func changeSliderValue() {
redSlider.value = redColor
greenSlider.value = greenColor
blueSlider.value = blueColor
}
func changeSliderLabel() {
let roundedRed = String(format: "%0.0f",(redColor))
let roundedGreen = String(format: "%0.0f",(greenColor))
let roundedBlue = String(format: "%0.0f",(blueColor))
redColorLabel.text = "Red: \(roundedRed)"
greenColorLabel.text = "Green: \(roundedGreen)"
blueColorLabel.text = "Blue: \(roundedBlue)"
}
override func viewDidLoad() {
super.viewDidLoad()
chageCurrentColorImage()
changeSliderValue()
}
}
Make the ColorsViewController
confirm to the HSBColorPickerDelegate
. And implement that method and store the value in ColorsViewController
. Also, I don't see that you are using the HSBColorPicker
in ColorsViewController
.