Picker selection not changing

Hello,

I have made a picker that is filled with data from an API endpoint. The data is retrieved and shown properly, however, when trying to change the selection on the picker, it does not work.

For simple demonstration i have put the picker in a empty view. Here is the code:


import SwiftUI

struct TestView: View {
    
    struct Subject: Hashable {
        let subjectId: Int
        let subjectName: String
    }
    @State var subjects: [Subject] = []
    @State var selectedSubject: Subject? = nil
    
    var body: some View {
        VStack {
            Picker(selection: $selectedSubject, label: Text("Kies een vak")) {
                ForEach(subjects, id: \.self) { subject in
                    Text(subject.subjectName).tag(subject)
                }
            }
            .frame(width: 300, height: 50)
            .background(Color.black.opacity(0.05))
            .cornerRadius(10)
            .onChange(of: selectedSubject) { newSubject in
                print("Chosen subject: \(newSubject?.subjectId ?? -1)")
            }
            
            Text("Chosen subject: \(selectedSubject?.subjectId ?? -1)")
        }
        .onAppear {
            Api().extractSubjects { subjects in
                DispatchQueue.main.async {
                    self.subjects = subjects.map { TestView.Subject(subjectId: $0.subjectId, subjectName: $0.subjectName) }
                }
            }
        }
    }
}

To better illustrate what I mean i have made a screenrecording:

I hope you guys and girls can help me out. If you need more info, please let me know!

Any help or suggestion is greatly appreciated, thanks!

Answered by Claude31 in 748789022

Read log error: Picker: the selection "nil" is invalid

You should change this:

    @State var selectedSubject: Subject? = nil

To set an initial value

    @State var selectedSubject: Subject = Subject()  // Select a Subject
Accepted Answer

Read log error: Picker: the selection "nil" is invalid

You should change this:

    @State var selectedSubject: Subject? = nil

To set an initial value

    @State var selectedSubject: Subject = Subject()  // Select a Subject

Yeah sadly you can't use an Optional value with a Picker in the same simple way you can normally do for Enum types. Instead, you need must tag each item casted as an Optional value. Here's an example from this SO answer to the question: Picker for optional data type in SwiftUI?:

struct FruitView: View {

    @State private var fruit: Fruit?

    var body: some View {
        Picker(selection: $fruit, label: Text("Fruit")) {
            Text("No fruit").tag(nil as Fruit?)
            ForEach(Fruit.allCases) { fruit in
                Text(fruit.rawValue).tag(fruit as Fruit?)
            }
        }
    }
}
Picker selection not changing
 
 
Q