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

Posted

技术标签:

【中文标题】文本未根据选择器正确更新【英文标题】: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 时应该始终采用的方式?

【问题讨论】:

【参考方案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

【讨论】:

第二个选择器实际上并不存在。我只是展示了两种显示我尝试过的选择器的方法,并澄清了为什么第二种方法没有按预期工作。

以上是关于文本未根据选择器正确更新的主要内容,如果未能解决你的问题,请参考以下文章

标签未随选择器视图更新

由枚举驱动的 SwiftUI 选择器:值未更新

UIPickerView 作为按钮操作并根据选择器的选定值设置文本字段的文本

根据复选框值操作日期选择器天数

材质 UI 月份选择器未显示正确的 UI

onAppear 不允许保存/更新选择器值的更改?