This code does not work, meaning onChange is never called and the variable is not changed when a dropdown option is selected.
struct ExamplePicker: View {
@State var val: Int32 = 2
var body: some View {
HStack {
Menu {
Picker(selection: $val, label: EmptyView()) {
Text("Val1").tag(1)
Text("Val2").tag(2)
Text("Val3").tag(3)
}
} label: {
HStack {
Text("Value: ")
Spacer()
Text(String(format: "%d", val))
Spacer()
}
}
.onChange(of: val) { newSelection in
print(">>> HERE")
}
}
}
}
but if you change val to type Int it works perfectly fine.
This looks like a bug to me
EDIT:
Solved – the problem is that in .tag() you need the EXACT same type.
so .tag(1) would be Int not Int32. and thus .tag(Int32(1)) is needed
2
Answers
It works fine when the
tag
values of thePicker
items have the same type as the state variable. Like this:When you do
.tag(1)
, the type of1
isInt
.tag
does not know anything about what type ofBinding
you have passed toselection:
– anyHashable
thing can go in there:By type inference,
1
intag(1)
is inferred to beInt
, because I repeat,tag
doesn’t know anything aboutselection:
.So the type of the
selection:
binding is different from the type of the tag. This means that when you select something in the picker, SwiftUI doesn’t know what it should change the selection value to. It also doesn’t know which option is currently selected, for the same reason.To make a
Int32
selection work, explicitly say that1
,2
,3
etc areInt32
s: