Skip to content

Instantly share code, notes, and snippets.

@akingdom
Last active November 8, 2023 04:36
Show Gist options
  • Save akingdom/75778998e0d435060d645c0be35f9c24 to your computer and use it in GitHub Desktop.
Save akingdom/75778998e0d435060d645c0be35f9c24 to your computer and use it in GitHub Desktop.
Convert an HTML-style web hexadecimal color string to a UIColour instance. See also C# version.

Swift 5.0

Swift 5.0 cannot use the #ffffff syntax directly. Here is the code I use for web-related projects. Supports alpha and three-digits.

Usage example (uppercase values are fine too):

    let hex = "#FADE2B"  // yellow
    let color = UIColor(fromHex: hex)

Supported string formats:

  • "fff" // RGB
  • "#fff" // #RGB
  • "ffff" // RGBA
  • "#ffff" // #RGBA
  • "ffffff" // RRGGBB
  • "#ffffff" // #RRGGBB
  • "ffffffff" // RRGGBBAA
  • "#ffffffff" // #RRGGBBAA

The digits represent Red, Green, Blue and Alpha (like transparency).

IMPORTANT

This is written for iOS (UIKit). For MacOS (AppKit), replace UIColor with NSColor.

Alternatives:

You can remove the # and store it as a 32-bit unsigned integer literal, denoted by a 0x prefix thus: 0xffffff. You still need code to convert this to a colour though.

If you're wanting a non-programatic way to get the color: Open a colour selector dialog and switch to Colour Sliders > RGB Sliders and paste/enter the value into the 'Hex Color #' box. (Don't paste the # hash symbol.)

Caveat:

Hex colours originating from Android are usually in format AARRGGBB and will thus require reformatting. e.g. let newColor = color.suffix(6).prefix(4) + color.prefix(2)

Source:

https://gist.github.com/akingdom/75778998e0d435060d645c0be35f9c24

// Swift 5.0
// Color from a web-style hex string
//
// By Andrew Kingdom
// MIT license
//
extension UIColor {
/// Initialises UIColor from a hexadecimal string. Color is clear if string is invalid.
/// - Parameter fromHex: supported formats are "#RGB", "#RGBA", "#RRGGBB", "#RRGGBBAA", with or without the # character
public convenience init(fromHex:String) {
var r = 0, g = 0, b = 0, a = 255
let offset = fromHex.hasPrefix("#") ? 1 : 0
let ch = fromHex.map{$0}
switch(ch.count - offset) {
case 8:
a = 16 * (ch[offset+6].hexDigitValue ?? 0) + (ch[offset+7].hexDigitValue ?? 0)
fallthrough
case 6:
r = 16 * (ch[offset+0].hexDigitValue ?? 0) + (ch[offset+1].hexDigitValue ?? 0)
g = 16 * (ch[offset+2].hexDigitValue ?? 0) + (ch[offset+3].hexDigitValue ?? 0)
b = 16 * (ch[offset+4].hexDigitValue ?? 0) + (ch[offset+5].hexDigitValue ?? 0)
break
case 4:
a = 16 * (ch[offset+3].hexDigitValue ?? 0) + (ch[offset+3].hexDigitValue ?? 0)
fallthrough
case 3: // Three digit #0D3 is the same as six digit #00DD33
r = 16 * (ch[offset+0].hexDigitValue ?? 0) + (ch[offset+0].hexDigitValue ?? 0)
g = 16 * (ch[offset+1].hexDigitValue ?? 0) + (ch[offset+1].hexDigitValue ?? 0)
b = 16 * (ch[offset+2].hexDigitValue ?? 0) + (ch[offset+2].hexDigitValue ?? 0)
break
default:
a = 0
break
}
self.init(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255, alpha: CGFloat(a)/255)
}
}
@akingdom
Copy link
Author

akingdom commented Jul 4, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment