I want to use a SwiftUI Picker to select different colors. Instead of using Text() for each item in a picker, I want to use a Rectangle() to visually show the color, but SwiftUI doesn’t like it and shows me a bunch of blank spaces. Here are my implementations:
struct TeamColorPicker: View {
@State var teamColor: ColorSquare = ColorSquare(color: .blue)
var listOfColorsAvailable: [String] = ["Red", "Blue", "Teal", "Green", "Yellow", "Orange"]
var body: some View {
Picker("Team Color", selection: $teamColor) {
ForEach(listOfColorsAvailable, id: .self) { colorString in
let color = Color(colorString)
ColorSquare(color: color)
.tag(color)
}
}
}
}
and
struct ColorSquare: View, Hashable {
var color: Color
static func == (lhs: ColorSquare, rhs: ColorSquare) -> Bool {
return lhs.color == rhs.color
}
func hash(into hasher: inout Hasher) {
hasher.combine(color)
}
var body: some View {
Rectangle().fill(color).aspectRatio(1.0, contentMode: .fill).scaleEffect(0.025)
}
}
Thank you in advance for any guidance!!
I read somewhere that the Picker expects the selection
element to conform to Hashable
, so I made the ColorSquare
struct for this reason.
2
Answers
It seems like the issue might be with using a custom type (ColorSquare) as the selection type for the Picker. The selection type must conform to the Hashable and Equatable protocols. In your case, ColorSquare conforms to Hashable, but you also need to make it conform to Equatable.
Here’s the modified ColorSquare struct:
Now, try updating your TeamColorPicker as follows:
P.S: I hope that if this is not correct, it at least helps you to find direction, all the best!
Picker has a number of limitations about what it can display.
The following example code shows how to display the
listOfColorsAvailable
but only with the
.wheel
and.inline
style picker.Note the selection
teamColor
, must match the type of thetag()
of the picker elements.Alternatively, using
Color
directly: