swiftswiftuienumsswiftui-foreachswiftui-picker

SwiftUI Picker not showing selected value


I am aware there are other questions about this, but none of them answer the question.

There are two slightly different cases that are resulting in the same behaviour: using an enum for the Picker options, and using an array. The app builds successfully with no errors or warnings.

I have tried several different variations of the Picker code but none work.

Here is the Picker using the array:

Text("Track")
                    Picker("", selection: $track) {
                        ForEach(tracks, id: \.self) { t in
                            Text(t.name).tag(t)
                            }
                    }
                    .labelsHidden()

and here is the array:

let tracks = [Track(name: "Portimao", length: 4.692, downforce: Rating.High, grip: Rating.Low, wear: Rating.High, fuel: Rating.Medium, pitTime: 15.5)]

The other one is very similar:

Text("Tyre")
                    Picker("", selection: $tyre) {
                        ForEach(TyreType.allCases, id: \.self) { tyre in
                            Text(String(describing: tyre)).tag(tyre)
                            }
                    }
                    .labelsHidden()
enum TyreType: CaseIterable, Identifiable {
    var id: TyreType {self}
    case Wet
    case ExtraSoft
    case Soft
    case Medium
    case Hard
}

When I try to select an option with either of the Pickers, all the options are shown and selectable, but when it is selected the Picker goes blank again.

.tag() and .self make no difference to the behaviour.


Solution

  • Here is some example code that shows how you can use the Pickers you show in your question.

    Note, the Picker selection var, need to be of the same type as the .tag() you use in the Picker.

    // for testing
    struct Track: Hashable {
        var name: String
        var length: Double
        //....
    }
    
    struct ContentView: View {
        // for testing
        let tracks = [Track(name: "Portimao", length: 4.692),
                      Track(name: "aaa", length: 123),
                      Track(name: "bbb", length: 456),
                      Track(name: "ccc", length: 789)]
        
        @State var track: Track = Track(name: "Portimao", length: 4.692) 
        @State var tyre: TyreType = TyreType.ExtraSoft
        
        var body: some View {
            
            Text("Selected track: \(track.name)")
            Picker("", selection: $track) {
                ForEach(tracks, id: \.self) { t in
                    Text(t.name).tag(t)
                }
            }.labelsHidden()
            
            Text("Selected tyre: \(tyre.rawValue)")
            Picker("", selection: $tyre) {
                ForEach(TyreType.allCases, id: \.self) { tyre in
                    Text(String(describing: tyre)).tag(tyre)
                }
            }.labelsHidden()
        }
    }
    
    enum TyreType: String, CaseIterable, Identifiable {
        var id: TyreType {self}
        case Wet
        case ExtraSoft
        case Soft
        case Medium
        case Hard
    }