If I have a SwiftUI Color
:
let col: Color = Color(red: 0.5, green: 0.5, blue: 0.5)
How do I get the RGB components from col
?
Like this maybe:
print(col.components.red)
In UIKit, I could use UIColor.getRed
but there doesn't seem to be an equivalent in SwiftUI.
You can ask for resolving Color
components in the given environment, because colors are different in different environments (for example in dark and light environments). In the following sample, I resolved it using the current environment of the used color.
struct ContentView: View {
@Environment(\.self) var environment
@State private var color = Color.red
@State private var components: Color.Resolved?
var body: some View {
VStack {
ColorPicker("Select your favorite color", selection: $color)
if let components {
Text("R: \(components.red)")
Text("G: \(components.green)")
Text("B: \(components.blue)")
Text("A: \(components.opacity)")
Text("HEX: \(components.description)")
}
}
.padding()
.onChange(of: color, initial: true) { components = color.resolve(in: environment) }
}
}
The code above has been written for iOS 17 beta 1 using Xcode 15 beta 1
There is a new initializer that takes a Color
and returns a UIColor
for iOS or NSColor
for macOS now. With the help of those you can implement the following extensions:
import SwiftUI
#if canImport(UIKit)
import UIKit
#elseif canImport(AppKit)
import AppKit
#endif
extension Color {
var components: (red: CGFloat, green: CGFloat, blue: CGFloat, opacity: CGFloat) {
#if canImport(UIKit)
typealias NativeColor = UIColor
#elseif canImport(AppKit)
typealias NativeColor = NSColor
#endif
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var o: CGFloat = 0
guard NativeColor(self).getRed(&r, green: &g, blue: &b, alpha: &o) else {
// You can handle the failure here as you want
return (0, 0, 0, 0)
}
return (r, g, b, o)
}
var hex: String {
String(
format: "#%02x%02x%02x%02x",
Int(components.red * 255),
Int(components.green * 255),
Int(components.blue * 255),
Int(components.opacity * 255)
)
}
}
Color.red.components.red // 0.9999999403953552 // <- SwiftUI Colors are not pure!