Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get RGB components from Color in SwiftUI

Tags:

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.

like image 960
Div Avatar asked Jun 13 '19 17:06

Div


People also ask

How do I use custom colors in SwiftUI?

Adding custom colors is actually simple, you add the color to the assets folder and then you write a few lines of code to use it anywhere you want in your project. Search for the assets folder in your project, once inside you'll see everything that's added to the folder such as images, your app icon, etc.


Video Answer


2 Answers

iOS 14 / macOS 10.16

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:

iOS / macOS

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)     } } 

Usage

Color.red.components.red // 0.9999999403953552 // <- SwiftUI Colors are not pure! 
like image 95
Mojtaba Hosseini Avatar answered Oct 08 '22 06:10

Mojtaba Hosseini


Waiting for an API I've abused CustomStringConvertible protocol for the simple rgba case where the color description format is #rrggbbaa

debugPrint(Color.red) debugPrint(Color(red: 1.0, green: 0.0, blue: 0.0)) debugPrint(Color(red: 1.0, green: 0.3, blue: 0.0)) debugPrint(Color(.sRGB, red: 1.0, green: 0.0, blue: 0.5, opacity: 0.3)) debugPrint(Color(hue: 1.0, saturation: 0.0, brightness: 1.0)) debugPrint(Color(.displayP3, red: 1.0, green: 0.0, blue: 0.0, opacity: 1.0).description)  red #FF0000FF #FF4C00FF #FF00804D #FFFFFFFF "DisplayP3(red: 1.0, green: 0.0, blue: 0.0, opacity: 1.0)" 

as you can see, things like Color.red just dump "red" but if you are working with simple RGB colors generated by code (ie from a color picker) then this is not too bad

extension SwiftUI.Color {     var redComponent: Double? {         let val = description         guard val.hasPrefix("#") else { return nil }         let r1 = val.index(val.startIndex, offsetBy: 1)         let r2 = val.index(val.startIndex, offsetBy: 2)         return Double(Int(val[r1...r2], radix: 16)!) / 255.0     }      var greenComponent: Double? {         let val = description         guard val.hasPrefix("#") else { return nil }         let g1 = val.index(val.startIndex, offsetBy: 3)         let g2 = val.index(val.startIndex, offsetBy: 4)         return Double(Int(val[g1...g2], radix: 16)!) / 255.0     }      var blueComponent: Double? {         let val = description         guard val.hasPrefix("#") else { return nil }         let b1 = val.index(val.startIndex, offsetBy: 5)         let b2 = val.index(val.startIndex, offsetBy: 6)         return Double(Int(val[b1...b2], radix: 16)!) / 255.0     }      var opacityComponent: Double? {         let val = description         guard val.hasPrefix("#") else { return nil }         let b1 = val.index(val.startIndex, offsetBy: 7)         let b2 = val.index(val.startIndex, offsetBy: 8)         return Double(Int(val[b1...b2], radix: 16)!) / 255.0     } } 
like image 33
Nicola Ferruzzi Avatar answered Oct 08 '22 05:10

Nicola Ferruzzi