Skip to main content

How to read the red, green, and blue values from a Color

About 3 minSwiftSwiftUIArticle(s)bloghackingwithswift.comcrashcourseswiftswiftuixcodeappstore

How to read the red, green, and blue values from a Color 관련

SwiftUI by Example

Back to Home

How to read the red, green, and blue values from a Color | SwiftUI by Example

How to read the red, green, and blue values from a Color

Updated for Xcode 15

New in iOS 17

SwiftUI's Color view doesn't always hold one specific color, and instead is only resolved to a specific value when it's being drawn on the screen. This allows the system to use slight variations between light and dark mode to ensure the optimal experience, but it also means the only way to get actual red, green, and blue (RGB) components out is to ask for the resolved color – ask the system “given this environment, what actual color values are being used?”

Resolving takes two steps: gaining access to the current environment, and pass that into a call to resolve(in:) on your color. You can then save the resulting data using Codable or whatever other data form you want.

For example, this lets the user choose any color they want, and displays its red, green, and blue components:

struct ContentView: View {
    @Environment(\.self) var environment
    @State private var color = Color.red
    @State private var resolvedColor: Color.Resolved?

    var body: some View {
        VStack {
            ColorPicker("Select your favorite color", selection: $color)

            if let resolvedColor {
                Text("Red: \(resolvedColor.red)")
                Text("Green: \(resolvedColor.green)")
                Text("Blue: \(resolvedColor.blue)")
                Text("Opacity: \(resolvedColor.opacity)")
            }
        }
        .padding()
        .onChange(of: color, initial: true, getColor)
    }

    func getColor() {
        resolvedColor = color.resolve(in: environment)
    }
}

Download this as an Xcode projectopen in new window

A color picker that displays its red, green, and blue components every time the color is changed.
A color picker that displays its red, green, and blue components every time the color is changed.

Important

The data is provided as Float rather than Double.

In that code, resolved gets set to a Color.Resolved type, which can be converted back into a new Color object or be converted to JSON or similar using Codable.

For example, we could convert our resolved color to JSON like this:

struct ContentView: View {
    @Environment(\.self) var environment
    @State private var color = Color.red

    @State private var resolvedColor: Color.Resolved?
    @State private var colorJSON = ""

    var body: some View {
        VStack {
            ColorPicker("Select your favorite color", selection: $color)

            if let resolvedColor {
                Text("Red: \(resolvedColor.red)")
                Text("Green: \(resolvedColor.green)")
                Text("Blue: \(resolvedColor.blue)")
                Text("Opacity: \(resolvedColor.opacity)")
            }

            Text("Color JSON: \(colorJSON)")
        }
        .padding()
        .onChange(of: color, initial: true, getColor)
    }

    func getColor() {
        resolvedColor = color.resolve(in: environment)

        if let colorData = try? JSONEncoder().encode(resolvedColor) {
            colorJSON = String(decoding: colorData, as: UTF8.self)
        }
    }
}

Download this as an Xcode projectopen in new window

A view that shows red, green, and blue values for a user color, and also the matching JSON data.
A view that shows red, green, and blue values for a user color, and also the matching JSON data.

Note

We're dealing with floating-point numbers, so you can expect some microscopic variations.

If you've loaded a resolved color and want to convert it back to a Color instance, just pass it into the initializer like this:

let resolvedColor = Color.Resolved(red: 0, green: 0.6, blue: 0.9, opacity: 1)

Rectangle()
    .fill(Color(resolvedColor).gradient)
    .ignoresSafeArea()

Download this as an Xcode projectopen in new window

A gentle blue gradient created from a resolved color.

Similar solutions…
How to create a date picker and read values from it | SwiftUI by Example

How to create a date picker and read values from it
How to create a picker and read values from it | SwiftUI by Example

How to create a picker and read values from it
How to create a segmented control and read values from it | SwiftUI by Example

How to create a segmented control and read values from it
SwiftUI tips and tricks | SwiftUI by Example

SwiftUI tips and tricks
All SwiftUI property wrappers explained and compared | SwiftUI by Example

All SwiftUI property wrappers explained and compared

이찬희 (MarkiiimarK)
Never Stop Learning.