Reputation: 905
I am trying to have a picker list all of a type, called Course
and then let the user select the appropriate course when adding a new Assignment
to the managed object context. The picker selection binding (courseIndex
) isn't updated when the user taps a row in the picker view. I'm not entirely sure how to fix the issue, nor do I know what is causing it. Any help is appreciated!
Here is the affected code:
struct NewAssignmentView: View {
@Environment(\.presentationMode) var presentationMode
@Environment(\.managedObjectContext) var context
@FetchRequest(entity: Course.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Course.name, ascending: true)]) var courses: FetchedResults<Course>
@State var name = ""
@State var hasDueDate = false
@State var dueDate = Date()
@State var courseIndex = 0
var body: some View {
NavigationView {
Form {
TextField("Assignment Name", text: $name)
Section {
Picker(selection: $courseIndex, label:
HStack {
Text("Course: ")
Spacer()
Text(self.courses[self.courseIndex].name ?? "").foregroundColor(self.courses[self.courseIndex].color).bold()
})
{
ForEach(self.courses, id: \.self) { course in
Text("\(course.name ?? "")").foregroundColor(course.color).tag(course)
}
}
}
Section {
Toggle(isOn: $hasDueDate.animation()) {
Text("Due Date")
}
if hasDueDate {
DatePicker(selection: $dueDate, displayedComponents: .date, label: { Text("Set Date:") })
}
}
}
[...]
Upvotes: 16
Views: 5806
Reputation: 962
When using optional binding values it's important that you explicitly provide the optional wrapping for the tag values because Swift doesn't automatically unwrap it for you and fails to equate a non-optional value with an optional one.
@Binding var optional: String?
Picker("Field", selection: $optional) {
// None option.
Text("None").tag(String?.none)
// Other fields.
ForEach(options) { option in
Text(option).tag(String?.some(option))
}
}
Upvotes: 40
Reputation: 257533
I cannot make your snapshot compilable, so just changed, here... I assume that as your selection is index, you have to use ranged ForEach
instead, like
ForEach(0 ..< self.courses.count) { i in
Text("\(self.courses[i].name ?? "")").foregroundColor(self.courses[i].color).tag(i)
}
PS. not sure about tag
usage, probably it might be not needed.
Upvotes: 1