SwiftUI实现Codable的伪Color
痛点
在使用SwiftUI时,可能需要将Color转换为JSON以便存储、传输,然而Color本身又难以get数值属性。
虽然可以写一个只包含rgb的颜色类,但是如果使用了ColorPicker这样的View又只能使用Color或者CGColor来实现,因此在重写ColorPicker和重写Color之间我选择重写Color。
实现目标
- Codable是最起码的
- 和Color或者CGColor的互转
- 在ColorPicker中大概能使用
SwiftUI中的Color和UIColor
Color
Color类虽然非常直观易用,内置了很多颜色,但是持久化存储挺麻烦的,好在可以和CGColor互转,于是就开始研究CGColor的存储
CGColor
相对Color而言,CGColor就看起来容易存储许多,不过有一点麻烦的是色彩空间的指定,所以我的实现里面只有sRGB和p3,其他色彩空间同理。
MyColor的实现
属性
var r: CGFloat
var g: CGFloat
var b: CGFloat
var alpha: CGFloat
var space : Space = .srgb
enum Space: String, Codable {
case srgb
case p3
}
和Color的转换
// 使用相似的方法创建
init(r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat) {
self.r = r
self.g = g
self.b = b
self.alpha = a
}
func toColor() -> Color {
return Color(toCGColor()).opacity(alpha)
}
和CGColor的转换
init(cgcolor: CGColor) {
let colorSpaceName : CGColorSpace = cgcolor.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)!
let colorComponents = cgcolor.components!
if colorComponents.count == 4 {
r = colorComponents[0]
g = colorComponents[1]
b = colorComponents[2]
alpha = colorComponents[3]
} else {
fatalError("cant convert cgcolor to mycolor")
}
switch colorSpaceName {
case CGColorSpace(name: CGColorSpace.sRGB): space = Space.srgb
case CGColorSpace(name: CGColorSpace.displayP3): space = Space.p3
default:space = Space.srgb
}
}
func toCGColor() -> CGColor {
return CoreGraphics.CGColor(colorSpace: colorSpace, components: [r,g,b,alpha])!
}
使用示例
import SwiftUI
struct ColorPickerWithMyColor: View {
@Binding var color: MyColor
@State var colorTemp : CGColor = .random()
var body: some View {
HStack {
ColorPicker(selection: $colorTemp){
// let c = Color.random()
}
.onChange(of: colorTemp, perform: { newColor in
color = MyColor(cgcolor: newColor)
})
}
.onAppear(perform: {
colorTemp = color.toCGColor()
})
}
}
MyColor的完整代码
import SwiftUI
class MyColor: Codable {
var r: CGFloat
var g: CGFloat
var b: CGFloat
var alpha: CGFloat
var space : Space = .srgb
enum CodingKeys: String, CodingKey {
case r,g,b,alpha,space
}
enum Space: String, Codable {
case srgb
case p3
}
init(r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat) {
self.r = r
self.g = g
self.b = b
self.alpha = a
}
init(cgcolor: CGColor) {
let colorSpaceName : CGColorSpace = cgcolor.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)!
let colorComponents = cgcolor.components!
if colorComponents.count == 4 {
r = colorComponents[0]
g = colorComponents[1]
b = colorComponents[2]
alpha = colorComponents[3]
} else {
fatalError("cant convert cgcolor to mycolor")
}
switch colorSpaceName {
case CGColorSpace(name: CGColorSpace.sRGB): space = Space.srgb
case CGColorSpace(name: CGColorSpace.displayP3): space = Space.p3
default:space = Space.srgb
}
}
func toCGColor() -> CGColor {
return CoreGraphics.CGColor(colorSpace: colorSpace, components: [r,g,b,alpha])!
}
func toColor() -> Color {
return Color(toCGColor()).opacity(alpha)
}
var colorSpace: CGColorSpace {
switch space {
case .srgb : return CGColorSpace(name: CGColorSpace.sRGB)!
case .p3 : return CGColorSpace(name: CGColorSpace.displayP3)!
}
}
static func random() -> MyColor {
return MyColor(r: .random(in: 0...1), g: .random(in: 0...1), b: .random(in: 0...1), a: .random(in: 0.5...1))
}
static func random() -> CGColor {
return MyColor.random().toCGColor()
}
}
extension MyColor: Equatable {
static func == (lop: MyColor, rop: MyColor) -> Bool {
return lop.toCGColor() == rop.toCGColor()
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgicgii
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13