文本未根据选择器正确更新

Text not updating correctly based on picker

这是我的模型

struct ListItemModel: Codable, Identifiable {
   let id: String  
   let name: String
}

这是将与选择器一起显示的视图。该列表将由外部来源填充,但我为此示例对其进行了简化。

struct TypeSelectionView: View {
    @State private var selected = 0
    
    let testList = [ListItemModel(id: "11", name: "name1"),
                        ListItemModel(id: "12", name: "name2")]
    
    var body: some View {
        VStack {
            Picker(selection: $selected, label: Text("Pick a Type")) {
                    ForEach(0 ..< testList.count) {
                        Text(testList[[=11=]].name)
                    }
            }.labelsHidden()
            
            Picker(selection: $selected, label: Text("Pick a Type")) {
                    ForEach(testList) {type in
                        Text(type.name)
                }
            }.labelsHidden()
            
            Text("Selected Type: \(testList[selected].name)")
            
            Spacer()
        }
    }
}



struct TypeSelectionView_Previews: PreviewProvider {
    static var previews: some View {
        TypeSelectionView()
    }
}

当第一个选择器更改时,第一个选择器正确地更改了页面上文本视图的显示,但第二个选择器没有。他们是让第二个 Picker 做同样的事情的方法吗,当你改变 Picker 时,文本视图会相应地更新 还是第一个选择器是您在 SwiftUI 中制作选择器时应该始终采用的方式?

您的第二个 Picker 不起作用的原因是 Picker 编辑的值 return 对应于项目的 id。对于第二个 Picker,它们是 String.

您可以对每个项目应用 .tag(),然后 Picker 会 return。例如,如果您添加一个明确的 tag 它将起作用:

Text(type.name).tag(testList.firstIndex(where: { [=10=].id == type.id })!)

或者,如果您将 id 值更改为 Int 并且 id 值对应于数组中的位置,则它会起作用。

由于实现 tag 的困难,很容易理解为什么许多开发人员选择只迭代 0 ..< testList.count

好的,这是我对堆栈溢出问题的第一个回答,我自己也是一个新手,但希望我能提供一些帮助。

放在Xcode中的代码显示了两个初始值为name1的选择器,但是当您更改第一个选择器时,第二个选择器和显示所选类型的文本会相应更改,但是因为两个选择器共享相同的真实来源 @State private var selected = 0,更改它会产生意想不到的副作用。

import SwiftUI

struct TypeSelectionView: View {
    @State private var selected = 0
    

    @State var testList = [ListItemModel(id: "11", name: "name1"),
        ListItemModel(id: "12", name: "name2")]
    @State var priorityTypes = ["low", "medium", "high", "critical"]

    var body: some View {
        VStack {
            Picker("Pick a Type", selection: $selected) {
                ForEach(0..<testList.count) {
                    Text(self.testList[[=10=]].name)
                }
            }.labelsHidden()

           Picker("Pick a Type", selection: $selected) {
               ForEach(0..<testList.count) {
                   Text(self.testList[[=10=]].name)
               }
           }.labelsHidden()

            Text("Selected Type: \(testList[selected].name)")

            Spacer()
        }
    }
}



struct TypeSelectionView_Previews: PreviewProvider {
    static var previews: some View {
        TypeSelectionView()
    }
}

struct ListItemModel: Codable, Identifiable {
    let id: String
    let name: String
}