SwiftUIがある場合Color
:
let col: Color = Color(red: 0.5, green: 0.5, blue: 0.5)
col
からRGBコンポーネントを取得するにはどうすればよいですか?
多分これのように:
print(col.components.red)
UIKitでは、UIColor.getRed
ですが、SwiftUIには同等のものがないようです。
答えはnoですまだ)APIはありませんが...
ほとんどのSwiftUI構造体には、private
のようなColor
のフィールドがあります。
Mirror
を使用してそのような情報を抽出できますが、効率的ではないことに注意してください。
教育目的でSwiftUI Color
の16進数表現を抽出する方法は次のとおりです。
これをコピーして---(Xcode 11プレイグラウンドに貼り付けます。
import UIKit
import SwiftUI
let systemColor = Color.red
let color = Color(red: 0.3, green: 0.5, blue: 1)
extension Color {
var hexRepresentation: String? {
let children = Mirror(reflecting: color).children
let _provider = children.filter { $0.label == "provider" }.first
guard let provider = _provider?.value else {
return nil
}
let providerChildren = Mirror(reflecting: provider).children
let _base = providerChildren.filter { $0.label == "base" }.first
guard let base = _base?.value else {
return nil
}
var baseValue: String = ""
dump(base, to: &baseValue)
guard let firstLine = baseValue.split(separator: "\n").first,
let hexString = firstLine.split(separator: " ")[1] as Substring? else {
return nil
}
return hexString.trimmingCharacters(in: .newlines)
}
}
systemColor.hexRepresentation
color.hexRepresentation
dumped
の場合、.red
、.white
などの色には多くの情報が含まれていないようです。
それらの「システム」名だけです。
▿ red
▿ provider: SwiftUI.(unknown context at $1297483bc).ColorBox<SwiftUI.SystemColorType> #0
- super: SwiftUI.(unknown context at $129748300).AnyColorBox
- base: SwiftUI.SystemColorType.red
Color
/red
/blue
コンポーネントでインスタンス化されたgreen
は代わりに使用します。
▿ #4C80FFFF
▿ provider: SwiftUI.(unknown context at $11cd2e3bc).ColorBox<SwiftUI.Color._Resolved> #0
- super: SwiftUI.(unknown context at $11cd2e300).AnyColorBox
▿ base: #4C80FFFF
- linearRed: 0.073238954
- linearGreen: 0.21404114
- linearBlue: 1.0
- opacity: 1.0
プレイグラウンドには、次のものが表示されます。
systemColor.hexRepresentation
戻り値nil
color.hexRepresentation
戻り値"#4C80FFFF"
色の説明の形式が#rrggbbaaである単純なrgbaケースでCustomStringConvertible
プロトコルを乱用したAPIを待機しています
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)"
ご覧のとおり、Color.redのようなものは "red"をダンプするだけですが、コードによって(つまり、カラーピッカーから)生成された単純なRGBカラーを使用している場合、これはそれほど悪くありません。
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
}
}