Color is insanely important in iOS design. The color of a design has the power to evoke different emotions and impressions; it can impart a warm and inviting feeling or a cold and sterile one. It can even convey a sense of modernity or outdatedness to the design. One critical piece of color, is transferring color to and from your iOS application with other applications and services. Today, most applications transfer color using RGBA HEX strings. But unfortunately, iOS doesn't have a built-in way to convert HEX strings to `UIColor` or SwiftUI's `Color` types.
In this quick snippet, we will learn how to convert HEX strings to UIColor and Color for UIKit and SwiftUI.
1.
In your new XCode project, create a file called `UIColor+Hex.swift` and add the following code:
extension UIColor {
// Initializes a new UIColor instance from a hex string
convenience init?(hex: String) {
var hexString = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if hexString.hasPrefix("#") {
hexString.removeFirst()
}
let scanner = Scanner(string: hexString)
var rgbValue: UInt64 = 0
guard scanner.scanHexInt64(&rgbValue) else {
return nil
}
var red, green, blue, alpha: UInt64
switch hexString.count {
case 6:
red = (rgbValue >> 16)
green = (rgbValue >> 8 & 0xFF)
blue = (rgbValue & 0xFF)
alpha = 255
case 8:
red = (rgbValue >> 16)
green = (rgbValue >> 8 & 0xFF)
blue = (rgbValue & 0xFF)
alpha = rgbValue >> 24
default:
return nil
}
self.init(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, alpha: CGFloat(alpha) / 255)
}
// Returns a hex string representation of the UIColor instance
func toHexString(includeAlpha: Bool = false) -> String? {
// Get the red, green, and blue components of the UIColor as floats between 0 and 1
guard let components = self.cgColor.components else {
// If the UIColor's color space doesn't support RGB components, return nil
return nil
}
// Convert the red, green, and blue components to integers between 0 and 255
let red = Int(components[0] * 255.0)
let green = Int(components[1] * 255.0)
let blue = Int(components[2] * 255.0)
// Create a hex string with the RGB values and, optionally, the alpha value
let hexString: String
if includeAlpha, let alpha = components.last {
let alphaValue = Int(alpha * 255.0)
hexString = String(format: "#%02X%02X%02X%02X", red, green, blue, alphaValue)
} else {
hexString = String(format: "#%02X%02X%02X", red, green, blue)
}
// Return the hex string
return hexString
}
}
2.
If you have a SwiftUI project, create a file called `Color+Hex.swift` and add the following code:
import SwiftUI
extension Color {
init?(hex: String) {
guard let uiColor = UIColor(hex: hex) else { return nil }
self.init(uiColor: uiColor)
}
func toHexString(includeAlpha: Bool = false) -> String? {
return UIColor(self).toHexString(includeAlpha: includeAlpha)
}
}
3.
Now you can use the `UIColor` and `Color` extensions to convert HEX strings to UIColor and Color for UIKit and SwiftUI. For example:
import SwiftUI
let hexString = "FF0000" // red color
let uiColor: UIColor? = UIColor(hex: hexString) // UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
let color: Color? = Color(hex: hexString) // Color(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
You can also pass in a hex string that has an alpha value. For example:
let hexString = "#43ff64d9" // rgba(255, 118, 145, 0.32)
let uiColor: UIColor? = UIColor(hex: hexString) // UIColor(red: 0.255, green: 0.463, blue: 0.855, alpha: 0.32)
let color: Color? = Color(hex: hexString) // Color(red: 0.255, green: 0.463, blue: 0.855, alpha: 0.32)
In case an invalid hex string is passed, the `UIColor` and `Color` extensions will return `nil`. For example:
let invalidHexString = "FF0000FF" // invalid hex string
let uiColor: UIColor? = UIColor(hex: invalidHexString) // nil
let color: Color? = Color(hex: invalidHexString) // nil
4.
If you want to convert the `UIColor` or `Color` to a hex string, you can use the `toHexString` method. For example:
let hexString = "FF0000" // red color
let uiColor: UIColor? = UIColor(hex: hexString) // UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
let hexString: String? = uiColor?.toHexString() // "#FF0000"
let hexStringFromColor: String? = Color(hex: hexString)?.toHexString() // "#FF0000"
You can also pass in a boolean value to the `toHexString` method to include the alpha value in the hex string. For example:
let hexString = "#43ff64d9" // rgba(255, 118, 145, 0.32)
let uiColor: UIColor? = UIColor(hex: hexString) // UIColor(red: 0.255, green: 0.463, blue: 0.855, alpha: 0.32)
let hexString: String? = uiColor?.toHexString(includeAlpha: true) // "#43FF64D9"
let hexStringFromColor: String? = Color(hex: hexString)?.toHexString(includeAlpha: true) // "#43FF64D9"
Bonus: Easy extension methods with DittoSwift!
We use the hex color strings all the time in our apps at Ditto. We also encourage that you do as well! We don't believe our database should support hex strings out of the box.
1.
Make sure your project has DittoSwift installed. Follow the instructions here. and get started with an account here! https://portal.ditto.live
2.
Create a new file called `Ditto+ColorExtensions.swift` and add the following code:
import SwiftUI
import DittoSwift
extension DittoDocumentPath {
func uiColorFromHexString() -> UIColor? {
guard let string = self.string else { return nil }
return UIColor(hex: string)
}
func colorFromHexString() -> Color? {
guard let string = self.string else { return nil }
return Color(hex: string)
}
}
extension DittoMutableDocumentPath {
func set(color: Color, includeAlpha: Bool = false, isDefault: Bool = false) {
self.set(color.toHexString(includeAlpha: includeAlpha))
}
func set(uiColor: UIColor, includeAlpha: Bool = false, isDefault: Bool = false) {
self.set(uiColor.toHexString(includeAlpha: includeAlpha))
}
func uiColorFromHexString() -> UIColor? {
guard let string = self.string else { return nil }
return UIColor(hex: string)
}
func colorFromHexString() -> Color? {
guard let string = self.string else { return nil }
return Color(hex: string)
}
}
Now your application can parse the `DittoDocumentPath`
let docs = ditto.store["cars"].find("make == $args.make", args: ["make": "Honda"]).exec()
docs.forEach { doc in
let uiColor: UIColor? = doc["color"].uiColorFromHexString()
// or
let color: Color? = doc["color"].colorFromHexString()
}
4.
In addition. you can mutate the `DittoMutableDocumentPath` with UIColor and Color extensions.
ditto.store["cars"].find("make == $args.make", args: ["make": "Honda"])
.update { mutableDoc in
mutableDoc["color"].set(Color.red)
}
Color is a vital part of any iOS app. It's important to be able to convert between hex strings and UIColor and Color once you need to transmit Color through a network. We hope this tutorial helps you in your next project whether you are using Ditto or not! Coming Soon: I'll provide another blog post on how to accomplish this in your next JetPack Compose project!