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.
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
}
}
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)
}
}
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
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"
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.
Make sure your project has DittoSwift installed. Follow the instructions here. and get started with an account here! https://portal.ditto.live
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)
}
}
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()
}
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!