【问题标题】:Text not updating correctly based on picker文本未根据选择器正确更新
【发布时间】:2020-08-09 19:14:52
【问题描述】:

这是我的模特

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

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

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[$0].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 正确地更改了页面上 Text 视图的显示,但第二个 Picker 没有。他们是让第二个 Picker 做同样的事情的方法吗,当你更改 Picker 时,Text 视图会相应地更新 还是第一个 Picker 是您在 SwiftUI 中制作 Picker 时应该始终采用的方式?

【问题讨论】:

    标签: ios swift swiftui picker


    【解决方案1】:

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

    您可以将.tag() 应用于每个项目,然后Picker 将返回它。例如,如果您添加了显式的tag,它将起作用:

    Text(type.name).tag(testList.firstIndex(where: { $0.id == type.id })!)
    

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

    由于实现tag 的困难,很容易看出为什么许多开发人员选择只在0 ..&lt; testList.count 上进行迭代。

    【讨论】:

      【解决方案2】:

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

      代码在 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[$0].name)
                      }
                  }.labelsHidden()
      
                 Picker("Pick a Type", selection: $selected) {
                     ForEach(0..<testList.count) {
                         Text(self.testList[$0].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
      }
      

      【讨论】:

      • 第二个选择器实际上并不存在。我只是展示了两种显示我尝试过的选择器的方法,并澄清了为什么第二种方法没有按预期工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      相关资源
      最近更新 更多