April 14th, 2023

Converting HEX strings to UIColor and Color for UIKit and SwiftUI

Learn how to convert HEX strings to UIColor and Color for UIKit and SwiftUI

Max Alexander

Max Alexander

Co-Founder/Chief Product Officer

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!

Get posts in your inbox

Subscribe to updates and we'll send you occasional emails with posts that we think you'll like.