How to fix Picker not showing selection in SwiftUI
Issue #716
I have an enum that conforms to CaseIterable
that I want to show in Picker
1 | enum Position: String, Codable, CaseIterable, Identifiable { |
It compiles and runs just fine, but Picker does not show current selection regardless of any Picker style I choose. It does not update Binding
at all.
The fix is to specify id
, it looks redundant because of enum conforms to Identifiable
, but it fixes the problem
1 | Picker(selection: $preference.position, label: Text("Position")) { |
Mismatch between rawValue and enum case itself
Reading ForEach once again
1 | init(_ data: Data, content: @escaping (Data.Element) -> Content) |
Available when Data conforms to RandomAccessCollection, ID is Data.Element.ID, Content conforms to View, and Data.Element conforms to Identifiable.
So in our case, we use rawValue
as id
for Identifiable
, so there’s mismatch between our selection
being enum case
and items in ForEach
, which uses rawValue
to uniquely identifies items. So our fix is to explicitly state that we want to use the enum case itself \.self
as id
for ForEach
What we can also do is to declare enum case itself as id
1 | enum Position: String, Codable, CaseIterable, Identifiable { |
The lesson learned here is we need to ensure the underlying type of selection
in List
and id
used in ForEach
are the same
Updated at 2020-12-23 06:05:08