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")