Normally I can display a list of items like this in SwiftUI:
enum Fruit {
case apple
case orange
case banana
}
struct FruitView: View {
@State private var fruit = Fruit.apple
var body: some View {
Picker(selection: $fruit, label: Text("Fruit")) {
ForEach(Fruit.allCases) { fruit in
Text(fruit.rawValue).tag(fruit)
}
}
}
}
This works perfectly, allowing me to select whichever fruit I want. If I want to switch fruit
to be nullable (aka an optional), though, it causes problems:
struct FruitView: View {
@State private var fruit: Fruit?
var body: some View {
Picker(selection: $fruit, label: Text("Fruit")) {
ForEach(Fruit.allCases) { fruit in
Text(fruit.rawValue).tag(fruit)
}
}
}
}
The selected fruit name is no longer displayed on the first screen, and no matter what selection item I choose, it doesn't update the fruit value.
How do I use Picker with an optional type?
The tag must match the exact data type as the binding is wrapping. In this case the data type provided to
tag
isFruit
but the data type of$fruit.wrappedValue
isFruit?
. You can fix this by casting the datatype in thetag
method:Bonus: If you want custom text for
nil
(instead of just blank), and want the user to be allowed to selectnil
(Note: it's either all or nothing here), you can include an item fornil
:Don't forget to cast the
nil
value as well.Why not extending the enum with a default value? If this is not what you are trying to achieve, maybe you can also provide some information, why you want to have it
optional
.