SwiftUI中实现一个Codable的伪Color

SwiftUI中实现一个Codable的伪Color,第1张

痛点

在使用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()
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993352.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存