SwiftUI Picker Help -- 根据另一个选择器的选择填充选择器

Posted

技术标签:

【中文标题】SwiftUI Picker Help -- 根据另一个选择器的选择填充选择器【英文标题】:SwiftUI Picker Help -- Populating picker based on the selection of another picker 【发布时间】:2021-03-16 21:48:54 【问题描述】:

我正在尝试根据另一个选择器的选择来填充一个选择器。我是 Swift 的新手,并且已经为此苦恼了太久。我确信它没有我做的那么困难,但我会很感激任何帮助。

我认为我最大的问题是将第一个选择器的选择传递给第二个选择器的数组名称。我使用过开关盒,试图传递选择原始值......等等。下面是我希望它在没有选择器绑定的情况下看起来的示例。谢谢

import SwiftUI

struct veggie: View 
    let veggies = ["Beans", "Corn", "Potatoes"]
    let beanList = ["Pole", "String", "Black"]
    let cornList = ["Peaches & Cream", "Sweet"]
    let potatoList = ["Yukon Gold", "Idaho"]
    @State private var selectedVeggie = "Bean"
    @State private var selectedBean = "Pole"
    @State private var selectedType = ""
    
            var body: some View 
                NavigationView
                    VStack
                        Form
                            Picker("Please choose a veggie", selection: $selectedVeggie)
                                
                                ForEach(veggies, id: \.self) 
                                    Text($0)
                                
                            
                            Text("You selected \(selectedVeggie)")
                            Picker("Type", selection: $selectedBean)
                                
                                ForEach(beanList, id: \.self) 
                                    Text($0)
                                
                            
                        
                         .navigationTitle("Veggie Picker")
                
            
        

【问题讨论】:

【参考方案1】:

我想你希望这有点动态,而不是用if 语句硬编码。为了实现这一点,我设置了一个带有蔬菜类型的enum,然后是一个将蔬菜类型映射到其子类型的字典。那些看起来像:

enum VeggieType : String, CaseIterable 
    case beans, corn, potatoes


let subTypes : [VeggieType: [String]] = [.beans: ["Pole", "String", "Black"],
                                         .corn: ["Peaches & Cream", "Sweet"],
                                         .potatoes: ["Yukon Gold", "Idaho"]]

然后,在视图中,我这样做了:

struct ContentView: View 
    @State private var selectedVeggie : VeggieType = .beans
    @State private var selectedSubtype : String?
    
    var subtypeList : [String] 
        subTypes[selectedVeggie] ?? []
    
    var body: some View 
        NavigationView
            VStack
                Form
                    Picker("Please choose a veggie", selection: $selectedVeggie)
                    
                        ForEach(VeggieType.allCases, id: \.self) 
                            Text($0.rawValue.capitalized)
                        
                    
                    Text("You selected \(selectedVeggie.rawValue.capitalized)")
                    Picker("Type", selection: $selectedSubtype)
                    
                        ForEach(subtypeList, id: \.self) 
                            Text($0).tag($0 as String?)
                        
                    
                
                 .navigationTitle("Veggie Picker")
        
    


selectedVeggie 现在输入为VeggieTypeselectedSubtype 是一个可选的 String,它没有初始值(尽管您可以根据需要设置一个)。

第一个选择器遍历VeggieType 的所有案例。第二个根据计算属性 subtypeList 动态更改,该属性从我之前创建的 subTypes 字典中获取项目。

tag 项很重要——我必须制作标签 as String?,因为 SwiftUI 希望 selection 参数和 tag() 完全匹配。


注意:你说你是 Swift 的新手,所以我会提到你已经将你的视图命名为 `veggie`——在 Swift 中,通常类型都有大写名称。我将我的命名为 `ContentView`,但您可以将其重命名为 `VeggieView` 或类似的名称。

【讨论】:

jnpdx,非常感谢。感谢您的代码和解释。标签项目是让我一直挂着的东西。我永远无法让选择参数匹配。这真的有助于我更多地理解这种语言。 也感谢您对类型命名的提醒。我知道,但你的评论重申了我们代码中结构和语法的重要性,即使它只是举一个例子。再次感谢。

以上是关于SwiftUI Picker Help -- 根据另一个选择器的选择填充选择器的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 如何让 ForEach 循环根据 Picker 中选定月份的天数进行迭代

禁用 SwiftUI SegmentedPickerStyle Picker 中的段?

SwiftUI:将动画添加到 Picker 而不将其添加到值中

当 Swiftui Picker 滚动其列表时触发的事件

SwiftUI 中的一排 Picker ***,为啥拖动滚动区域从屏幕上的 Picker 控件偏移?

SwiftUI 为啥 Picker 上的输入不起作用?