The following code successfully shows a set of colors and displays the selected color when the colors are tapped, similar to the standard ColorPicker
. What I would like to be able to do is use this custom color picker in other views, in a similar way as the standard ColorPicker
. My issue is that I cannot expose the selected color to other views.
ContentView:
struct ContentView: View {
var body: some View {
VStack{
CustomColorPicker()
}
}
}
Custom Color Picker:
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)
}
}
}
I have tied using a model/ObservableObject
to be able to capture the selected color in other views but it doesn't when you select the colors.
How can I make the Rectangle
in ContentView
update its fill color when a color in the color picker is tapped?
Or in general, what would be the best way to create a reusable custom color picker?
Using an ObservableObject
Content View
struct ContentView: View {
@ObservedObject var cModel = ColorPickerModel()
var body: some View {
VStack{
CustomColorPicker()
Rectangle()
.fill(cModel.selectedColor)
.frame(width: 100, height: 100)
}
}
}
Custom Color Picker
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)
}
}
}