RT

Convert a hex color to UIColor in Swift

Here is a simple extension to UIColor for creating colors from hex strings. It can parse hex colors in #RRGGBB and #RRGGBBAA formats, as well as the #RGB shorthand:

import UIKit

extension UIColor {
    convenience init?(hex: String) {
        let scanner = Scanner(string: hex)
        scanner.charactersToBeSkipped = nil

        // Consume optional `#`
        _ = scanner.scanString("#")

        switch scanner.charactersLeft() {
        case 6, 8:
            guard let red = scanner.scanHexByte(),
                  let green = scanner.scanHexByte(),
                  let blue = scanner.scanHexByte() else {
                return nil
            }

            var alpha: UInt8 = 255

            // Parse alpha if available
            if scanner.charactersLeft() == 2 {
                guard let parsedAlpha = scanner.scanHexByte() else {
                    return nil
                }

                alpha = parsedAlpha
            }

            self.init(
                red: CGFloat(red) / 255,
                green: CGFloat(green) / 255,
                blue: CGFloat(blue) / 255,
                alpha: CGFloat(alpha) / 255
            )
        case 3:
            guard let red = scanner.scanHexNibble(),
                  let green = scanner.scanHexNibble(),
                  let blue = scanner.scanHexNibble() else {
                return nil
            }

            self.init(
                red: CGFloat(red) / 15,
                green: CGFloat(green) / 15,
                blue: CGFloat(blue) / 15,
                alpha: 1
            )
        default:
            return nil
        }
    }
}

private extension Scanner {
    func scanHexNibble() -> UInt8? {
        guard let character = scanCharacter(), character.isHexDigit else {
            return nil
        }

        return UInt8(String(character), radix: 16)
    }

    func scanHexByte() -> UInt8? {
        guard let highNibble = scanHexNibble(), let lowNibble = scanHexNibble() else {
            return nil
        }

        return (highNibble << 4) | lowNibble
    }

    func charactersLeft() -> Int {
        return string.count - currentIndex.utf16Offset(in: string)
    }
}

To use it, simply call the new initializer with a hex string:

let color = UIColor(hex: "#9082F8")

See also