
目录
[ColorPicker 颜色选择器 从Color获取RGB](#ColorPicker 颜色选择器 从Color获取RGB)
颜色的基本知识
颜色的表示最常见的是RGB表示法,但是还有一些别的表示法,比如HSL,具体遇到的时候不要惊慌,每种表示法都是可以互相转换的。如果用过adobe的全家桶中的东西,会知道出版业用的颜色表示法是减色法,三原色是CMY(青色、品红和黄色),因为工业原料的原因,这三种色兑不出纯黑,所以打印机还需要单独的黑色墨盒(当然,这也符合成本经济性,但是不是决定性的理由)。扯这么多就让你知道,RGB只是颜色表示法的一种,不是唯一。
RGB表示法每种颜色通常用一个字节来表示,也就是0-255,共256个档次。字节这概念不够高大上,所以高级语言用浮点数,也就是百分比来表示颜色,255就是100%,也就是1.0。
所以swift的Color构造时RGB参数通常写作颜色值/255。
自定义颜色
下面的代码是一个标准的自定义颜色的界面:
Swift
@State var R: CGFloat = 0
@State var G: CGFloat = 0
@State var B: CGFloat = 0
var body: some View {
Form {
Rectangle()
.fill(Color(red: R / 255, green: G / 255, blue: B / 255))
.frame(height: 200)
Text("R \(Int(R))\nG \(Int(G))\nB \(Int(B))")
Slider(value: $R, in: 0...255, step: 1).accentColor(.red)
Slider(value: $G, in: 0...255, step: 1).accentColor(.green)
Slider(value: $B, in: 0...255, step: 1).accentColor(.blue)
}
}
初始:

随便弄一个颜色:

代码很简单,没什么好解释的。其实我更愿意用整数,但是Slider只能绑定浮点数,所以只能用浮点数。
ColorPicker 颜色选择器 从Color获取RGB
这个系统组件比我们自己做的完善一些,但是绑定的是Color类型,Color类型有个大问题,不能直接获得RGB,甚至没有提供间接方法,要想实现这个功能,必须借助UIColor对象。
下面的示例通过ColorPicker和之前的代码联动:
Swift
@State var ColorValue:Color = .black
ColorPicker("颜色",selection: $ColorValue)
.onChange(of: ColorValue) {
var uicolor: UIColor {.init(ColorValue)}
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
uicolor.getRed(&r, green: &g, blue: &b,alpha: &a)
R = r*255
G = g*255
B = b*255
}
代码在onChange里手动将选取的Color值同步到之前的RGB上。UIColor可以用init(Color)来构造,然后用UIColor的getRed方法来获取RGBA(处处显示着设计混乱,getRed为什么获取RGBA啊?偷懒了吗?alpha是透明度,本质上不是颜色,而是颜色叠加操作,Color的构造不包含alpha)。获取到的值是百分比,因此放入我们定义的RGB时要乘以255,不然显示的时候总是黑色(因为数值太小)。
初始:

选择颜色:

选择的时候就已经直接在背景上生效了。选择颜色有三个页面,三种方式,滑块方式会显示RGB值,由于我们用了数值转换,转换后的值和这里显示的可能会略有差别,这就是浮点数的问题(正经C/C++程序员不到万不得已是不会使用浮点数的)。
滑块方式:

关闭后:

注意到三个值都小了1吧。为了避免这个问题可以用浮点数来保存,界面显示*255,不过转成整数免不了精度问题。
如果不是专门折腾颜色,一般用ColorPicker也就满足需要了。