所以基本上我有一个主题数组,一个主题的一个属性是RGBAColor,它基本上是4个双精度.我故意不存储 colored颜色 struct ,因为我不希望像 colored颜色 这样的UI东西出现在我的模型中,它是独立于用户界面的.在我的ViewModel中,我将这个RGBAColor"解释"为一个普通的 colored颜色 struct .

我希望用户能够通过 colored颜色 Select 器更改主题的 colored颜色 属性,但由于ColorPicker接受 colored颜色 的绑定,而不是RGBAColor,所以我遇到了一些麻烦.有人告诉我,提示是创建一个到计算变量的绑定,所以我做了一个

extension Theme {

    var color: Binding<Color> {
        Binding {
            return Color(rgbaColor: self.rgbaColor)
        } set: { newRGBAColor in
            self.rgbaColor = RGBAColor(color: newRGBAColor)
        }
    }
}

但这是行不通的,因为self 是不变的.我怎么才能解决这个问题呢?

struct ThemeEditor: View {
    @Binding var theme: Theme

    var colorSection: some View {
        Section(header: Text("Colors")) {
            VStack {
                ColorPicker("Selection", selection: $theme.color)
            }
        }
    }
}
struct RGBAColor: Codable, Equatable, Hashable {
    let red: Double
    let green: Double
    let blue: Double
    let alpha: Double
}
extension RGBAColor {
    init(color: Color) {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        if let cgColor = color.cgColor {
            UIColor(cgColor: cgColor).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        }
        self.init(red: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha))
    }
    
    init(_ red: Double, _ green: Double, _ blue: Double, _ alpha: Double) {
        self.init(red: red/255, green: green/255 , blue: blue/255, alpha: alpha)
    }
}

extension Color {
    init(rgbaColor rgba: RGBAColor) {
        self.init(.sRGB, red: rgba.red, green: rgba.green, blue: rgba.blue, opacity: rgba.alpha)
    }
}

struct Theme: Identifiable, Codable, Hashable {
    var name: String
    var emojis: String
    var id: Int
    var numberOfPairsOfCards: Int
    var rgbaColor: RGBAColor
    
    fileprivate init(name: String, emojis: String, id: Int, numberOfPairsOfCards: Int, rgbaColor: RGBAColor) {
        self.name = name
        self.emojis = emojis
        self.id = id
        self.numberOfPairsOfCards = numberOfPairsOfCards
        self.rgbaColor = rgbaColor
    }
}

推荐答案

你只需要把它放在视线中,就像

struct ThemeEditor: View {
    @Binding var theme: Theme

    var color: Binding<Color> {     // << here !!
        Binding {
            return Color(rgbaColor: theme.rgbaColor)
        } set: { newRGBAColor in
            theme.rgbaColor = RGBAColor(color: newRGBAColor)
        }
    }

    var colorSection: some View {
        Section(header: Text("Colors")) {
            VStack {
                ColorPicker("Selection", selection: self.color) // << here !!
            }
        }
    }

    // ...
}

使用Xcode 13.4进行测试

Ios相关问答推荐

SwiftUI中的视频时间轴

阿拉伯文变音符号(Harakat)在文本对齐的UILabel中未对齐

如何在SwiftUI中以一定Angular 绘制直线(&A)

在SwiftUI中为圆角矩形创建均匀分布的点轮廓

在滚动视图中固定页眉,但在页眉上方嵌入元素

OnTapGesture在其修改的视图外部触发

发生错误.请稍后重试.在 App Store 连接中

SwiftUI 故障/错误 - 在 LazyVStack 和 ScrollView 中使用 AVPlayer 时状态栏不显示

SwiftUI:同时拖动父视图和子视图,但手指分开

如何根据条件快速将返回类型设为 LinearGradient 或 AngularGradient?

iOS 如何使用 Alamofire 解析 JSON 可编码数组

如何根据设备时间设置 Flutter 应用时间线?

从视图模型中更新 EnvironmentObject

@Environment 的存在会导致列表在滚动时不断重建其内容

使用导航控制器在prepareForSegue中设置数据

从 NSData 或 UIImage 中查找图像类型

刷新由 Xcode 7 管理的团队配置文件中的设备?

Storyboard Segue 从视图控制器到自身

在 iOS 上编写文件

Xcode 5 和 iOS 7:架构和有效架构