According to Apple's documentation regarding Picker in SwiftUI using an Enum, if the enum conforms to the Identifiable
protocol in addition to CaseIterable
, a picker iterating over all cases should update the bound variable natively.
I tested it, and it does not work as expected.
enum Flavor: String, CaseIterable, Identifiable {
case chocolate
case vanilla
case strawberry
var id: String { self.rawValue }
}
struct EnumView: View {
@State private var selectedFlavor = Flavor.chocolate
var body: some View {
VStack {
Picker("Flavor", selection: $selectedFlavor) {
ForEach(Flavor.allCases) { flavor in
Text(flavor.rawValue.capitalized)//.tag(flavor)
}
}
Text("Selected flavor: \(selectedFlavor.rawValue)")
}
}
}
However, if I pass a tag
for each view, it works.
What's happening here? Is the Apple documentation wrong? The selectedFlavor
variable expects a value of type Flavor
, but the id used in the picker is actually a String
.
Thanks.
For a Picker
to work properly, its elements need to be identified.
Note that the selectedFlavor
variable is of type Flavor
. Which means the options in the Picker should be identified as Flavors (not Strings).
However, in your code your id
is of type String
:
var id: String { self.rawValue }
You can either:
tag
(of type Flavor
):
Text(flavor.rawValue.capitalized)
.tag(flavor)
Flavor
to Identifiable
by providing a custom id
of type Flavor
:
var id: Flavor { self }
id
parameter (of type Flavor
) explicitly in the ForEach
:
ForEach(Flavor.allCases, id: \.self) { ... }
selectedFlavor
to be a String:
@State private var selectedFlavor = Flavor.chocolate.rawValue