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

SwiftUI Picker Help -- Populating picker based on the selection of another picker

我正在尝试根据另一个选择器的选择来填充一个选择器。我是 Swift 的新手,为此苦苦思索了太久。我确信它没有我做的那么难,但我将不胜感激任何帮助。

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

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([=10=])
                                }
                            }
                            Text("You selected \(selectedVeggie)")
                            Picker("Type", selection: $selectedBean)
                                {
                                ForEach(beanList, id: \.self) {
                                    Text([=10=])
                                }
                            }
                        }
                    }     .navigationTitle("Veggie Picker")
                }
            }
        }

我想您希望它是动态的,而不是用 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([=11=].rawValue.capitalized)
                        }
                    }
                    Text("You selected \(selectedVeggie.rawValue.capitalized)")
                    Picker("Type", selection: $selectedSubtype)
                    {
                        ForEach(subtypeList, id: \.self) {
                            Text([=11=]).tag([=11=] as String?)
                        }
                    }
                }
            }     .navigationTitle("Veggie Picker")
        }
    }
}

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

第一个选择器遍历 VeggieType 的所有情况。第二个根据计算的 属性 subtypeList 动态变化,它从我之前创建的 subTypes 字典中获取项目。

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


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