【问题标题】:Custom Reusable Color Picker not updating colors in other views自定义可重用颜色选择器不更新其他视图中的颜色
【发布时间】:2022-01-06 14:51:39
【问题描述】:

以下代码成功显示了一组颜色,并在点击颜色时显示选定的颜色,类似于标准的ColorPicker。我想做的是在其他视图中使用此自定义颜色选择器,其方式与标准 ColorPicker 类似。我的问题是我无法将所选颜色公开给其他视图。

内容视图:

    struct ContentView: View {
        var body: some View {
            VStack{
            CustomColorPicker()
            }
        }
    }

自定义颜色选择器:

    struct CustomColorPicker: View {
        var colors: [UIColor] = [.red, .green, .blue, .purple, .orange]
        
        @State var selectedColor = UIColor.systemGray6

        var body: some View {
            VStack {
                Rectangle()
                    .fill(Color(selectedColor))
                    .frame(width: 45, height: 45)
                
                HStack(spacing: 0) {
                    ForEach(colors, id: \.self) { color in
                        Button {
                            selectedColor = color
                        } label: {
                            Color(color)
                                .border(Color.gray, width: color == selectedColor ? 2 : 0)
                        }
                    }
                }
                .frame(height: 50.0)
            }
        }
    }

我已使用model/ObservableObject 绑定,以便能够在其他视图中捕获选定的颜色,但当您选择颜色时它不会。

当点击颜色选择器中的颜色时,如何使ContentView 中的Rectangle 更新其填充颜色?

或者一般来说,创建可重复使用的自定义颜色选择器的最佳方法是什么?

使用 ObservableObject

内容视图

    struct ContentView: View {
        
        @ObservedObject var cModel = ColorPickerModel()
        
        var body: some View {
            VStack{
            CustomColorPicker()
                
                Rectangle()
                    .fill(cModel.selectedColor)
                    .frame(width: 100, height: 100)
            }
        }
    }

自定义颜色选择器

    class ColorPickerModel:ObservableObject{
        @Published var selectedColor:Color = Color.orange
    }

    struct CustomColorPicker: View {
        var colors: [UIColor] = [.red, .green, .blue, .purple, .orange]
        
        @StateObject var cModel = ColorPickerModel()

        var body: some View {
            VStack {
                Rectangle()
                    .fill(cModel.selectedColor)
                    .frame(width: 45, height: 45)
                
                HStack(spacing: 0) {
                    ForEach(colors, id: \.self) { color in
                        Button {
                            cModel.selectedColor = Color(color)
                        } label: {
                            Color(color)
                                //.border(Color.gray, width: color == selectedColor ? 2 : 0)
                        }
                    }
                }
                .frame(height: 50.0)
            }
        }
    }

【问题讨论】:

  • 在你的第一个例子中。使状态成为可重用的绑定。然后像存储其他任何内容一样存储该值,以便您可以在任何地方访问它。
  • @loremipsum - 您介意在@Binding 上详细说明吗?抱歉,我一般对@Binding 或 SwiftUI 没有太多经验。谢谢

标签: swiftui color-picker observableobject


【解决方案1】:
import SwiftUI

struct MyColorView: View {
    //Source of truth
    @StateObject var cModel = MyColorViewModel()
    
    var body: some View {
        VStack{
            CustomColorPicker(selectedColor: $cModel.selectedColor)
            
            Rectangle()
            //Convert to the View Color
                .fill(Color(cModel.selectedColor))
                .frame(width: 100, height: 100)
        }
    }
}
//This will serve as the source of truth for this View and any View you share the ObservableObject with
//Share it using @ObservedObject and @EnvironmentObject
class MyColorViewModel:ObservableObject{
    //Change to UIColor the types have to match
    @Published var selectedColor: UIColor = .orange
}
struct CustomColorPicker: View {
    var colors: [UIColor] = [.red, .green, .blue, .purple, .orange]
    //You can now use this Picker with any Model
    //Binding is a two-way connection it needs a source of truth
    @Binding var selectedColor: UIColor
    
    var body: some View {
        VStack {
            HStack(spacing: 0) {
                ForEach(colors, id: \.self) { color in
                    Button {
                        selectedColor = color
                    } label: {
                        Color(color)
                            .border(Color.gray, width: color == selectedColor ? 2 : 0)
                    }
                }
            }
            .frame(height: 50.0)
        }
    }
}
struct MyColorView_Previews: PreviewProvider {
    static var previews: some View {
        MyColorView()
    }
}

试试Apple SwiftUI Tutorials,这是一个好的开始。

【讨论】:

  • 成功了。我会努力了解更多关于@Binding的信息,非常感谢!
  • 正如我所说,它找到了但我很难在@Published var selectedColor: UIColor = .orange@Binding var selectedColor: UIColor 之间建立联系,我更改了@Binding var 的名称,它仍然有效。两个变量之间的联系发生在哪里? @Published var 在什么时候更新为所选颜色?抱歉,我不太明白这两个属性包装器之间的关系。
  • $fs_tigre 连接发生在您在 MyColorView 中看到 $ 的位置。视图模型与那里的 Binding 连接。然后,当您点击颜色时,您设置变量
猜你喜欢
  • 2013-07-18
  • 2018-07-20
  • 2021-10-24
  • 2014-04-11
  • 2020-10-14
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多