SwiftUI选择器选中绑定未更新

14
我试图让一个选择器列出所有类型为Course的项目,当用户添加新的Assignment到托管对象上下文时,让用户选择适当的课程。当用户点击选择器视图中的一行时,选择器的选择绑定(courseIndex)不会更新。我不确定如何解决这个问题,也不知道是什么原因导致的。希望能得到任何帮助!
以下是受影响的代码:
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:") })
                }
            }
        }
[...]
2个回答

38

在使用可选绑定值时,重要的是你明确为标签值提供可选包装,因为Swift不会自动展开它,而且无法将非可选值与可选值相等。

@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))
    }
}

3
这就是我需要阅读的内容!谢谢你!! - KevinF
4
这个可以用,谢谢!仅仅使用.tag(option)不能正常工作似乎很荒谬,但SwiftUI的工作方式却很神秘。 - stef
1
惊人!我整整一天都在墙上撞头 - orelzion
1
两年后,这个问题终于找上门来了。太棒了! - Krames
1
它可以正常运行,但写.tag(option as String?) 更加简单直接。 - soundflix
对于对象,只需使用 Text(object.name).tag(object ?? nil) 即可。虽然不是很合理,但却有效。经过数小时的查找错误后得到了这个方法。 - Stefano Mtangoo

2

我无法使你的快照可编译,所以进行了一些更改... 我假设你选择了索引,因此必须使用带范围的 ForEach,例如:

ForEach(0 ..< self.courses.count) { i in
    Text("\(self.courses[i].name ?? "")").foregroundColor(self.courses[i].color).tag(i)
}

注:不确定tag的使用方式,可能不需要。


修好了!非常感谢! - Kevin Olmats

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接