From Hex to Color and Back in SwiftUI

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Search for a command to run...

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Hello!!! thanks for the blog.!! An erro is in RGBA HexToUIColor
This works OK..
a = CGFloat((hexNumber & 0xff000000) >> 24) / 255 r = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255 g = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255 b = CGFloat(hexNumber & 0x000000ff) / 255
Best for you!! Maximiliano Taccone
WWDC26 kicked off on June 8, 2026. The information in this article reflects the information published by Apple on that date. There are 14 new frameworks. Name Description AccessoryAccess Manage

WWDC25 kicked off on June 9, 2025. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AlarmKitSchedule prominent alarms and countdowns to help people manage their time. AVR...

WWDC25 is almost here, and I couldn’t be more excited! Whether you're attending the official events, community meetups, or just soaking in the energy around Cupertino, there’s no better time to connect, share ideas, and celebrate everything we love a...

In this blog post, I’ll share an observation and advice regarding the caching behavior of network responses by Apple’s APIs. If you are unfamiliar with caching of network responses then I recommend Apple’s article Accessing cached data that introduce...
WWDC24 kicked off on June 10, 2024. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AccessorySetupKitUse AccessorySetupKit to discover accessories with Bluetooth or Wi-Fi...

Bart Jacobs wrote a wonderful article From Hex to UIColor and Back in Swift and my article builds on top of his work. I was wondering how the same can be achieved in SwiftUI with its Color struct.
You don't need UIKit for this. Create an extension, using a Foundation string parser to scan for a long long value from the hexadecimal representation and finally initializing Color with help of the underlying CGColor.
import SwiftUI
extension Color {
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, opacity: a)
}
}
Two differences to Barts article:
UInt64 and scanHexInt32 because scanHexInt32 was deprecated in iOS 13Color initializer and pass alpha as opacity (there is no alpha parameter in Color's initializer). I can avoid using UIKit :)Remark: It is also possible to initialize Color with a Core Graphics representation. Be aware that you have to use init(srgbRed:green:blue:alpha:) and not init(red:green:blue:alpha:) because iOS uses sRGB color space.
According to Apple's documentation I was hoping to leverage the Core Graphics representation of the color directly from Color with its optional instance property cgColor.
You can get a CGColor instance from a constant SwiftUI color. This includes colors you create from a Core Graphics color, from RGB or HSB components, or from constant UIKit and AppKit colors. For a dynamic color, like one you load from an Asset Catalog using init(_:bundle:), or one you create from a dynamic UIKit or AppKit color, this property is nil.
However, in my tests the property was always nil. Even for constant SwiftUI colors like Color.blue.
UIKit is needed to ensure getting the underlying Core Graphics representation. Once we created UIColor from Color then accessing the Core Graphics representations and the color components is easy. Please read Bart's article if you wanna know more about the String formatters used here.
import SwiftUI
import UIKit
extension Color {
func toHex() -> String? {
let uic = UIColor(self)
guard let components = uic.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 a != Float(1.0) {
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))
}
}
}
It is possible, without UIKit, to create a Color instance from a hex string. But you need UIKit as bridging mechanism to create a hex string from a Color instance.
The two extensions work nicely and produce the same visual color as demonstrated below.
