Dan Donaldson
Dan Donaldson

Reputation: 1293

Dow can Swift's UIColorWell provide a hex representation of the selectedColor?

I'm using a couple of colorWell instances, and while I have no problem getting the selectedColor, I haven't found anything to indicate how to get an RGB hexadecimal representation, apart from writing my own conversion.

Because the colorWell actually displays this information, it must be available. Does anyone have any information on where this property is accessible?

Upvotes: 0

Views: 228

Answers (1)

KinneyKare
KinneyKare

Reputation: 118

This was a workaround after doing some searching and some testing.

Make a extension class of UIColor

import UIKit

extension UIColor {

    // MARK: - Initialization

    convenience init?(hex: String) {
        var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
        hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")

        var rgb: UInt64 = 0

        var r: CGFloat = 0.0
        var g: CGFloat = 0.0
        var b: CGFloat = 0.0
        var a: CGFloat = 1.0

        let length = hexSanitized.count

        guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }

        if length == 6 {
            r = CGFloat((rgb & 0xFF0000) >> 16) / 255.0
            g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0
            b = CGFloat(rgb & 0x0000FF) / 255.0

        } else if length == 8 {
            r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0
            g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0
            b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0
            a = CGFloat(rgb & 0x000000FF) / 255.0

        } else {
            return nil
        }

        self.init(red: r, green: g, blue: b, alpha: a)
    }

    // MARK: - Computed Properties

    var toHex: String? {
        return toHex()
    }

    // MARK: - From UIColor to String

    func toHex(alpha: Bool = false) -> String? {
        guard let components = cgColor.components, components.count >= 3 else {
            return nil
        }

        let r = Float(components[0])
        let g = Float(components[1])
        let b = Float(components[2])
        var a = Float(1.0)

        if components.count >= 4 {
            a = Float(components[3])
        }

        if alpha {
            return String(format: "%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255))
        } else {
            return String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
        }
    }
}

Create your UIColorWell: I did in storyboard the dragged it to my ViewController class.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var colorWell: UIColorWell!
    @IBOutlet weak var geofence: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupColorWell()
        geofence.layer.cornerRadius = geofence.frame.size.height / 2
    }
    private func setupColorWell() {
        colorWell.title = "Pick Your Color"
        colorWell.addTarget(self, action: #selector(colorChanged), for: .valueChanged)
    }
    
    @objc private func colorChanged() {
        geofence.backgroundColor = colorWell.selectedColor
        guard let hexValue = colorWell.selectedColor?.toHex else { return }
        print(hexValue)
    }
}

In the code above (in the colorChanged function) you can see how I create a hexValue from the selectedColor we get back from the color well. the Selected color is of type UIColor so we can unwrap it and use the .toHex function we created in our extension class. I printed out the hexValue just to verify it was in fact giving us the correct hex value.

NOTE: My project I used a view called "geofence" you can ignore that and set the selectedColor to whatever your needs might be. I will post an image of my storyboard to clarify a bit further as well.

enter image description here

You can find my code for this here: GITHUB

Upvotes: 1

Related Questions