简体   繁体   English

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

[英]SwiftUI Picker Help — Populating picker based on the selection of another picker

I am trying to populate a picker based on the selection of another picker.我正在尝试根据另一个选择器的选择来填充一个选择器。 I am new to Swift and have been beating my head on this for way too long.我是 Swift 的新手,并且在这个问题上困扰我太久了。 I am sure its not as difficult as I am making it but I would appreciate any assistance.我确信它没有我做的那么困难,但我会很感激任何帮助。

I think my biggest issue is passing the selection of the first picker to the array name of the second.我认为我最大的问题是将第一个选择器的选择传递给第二个选择器的数组名称。 I have used switch case, tried to pass the selection raw value...etc.我使用过开关盒,试图传递选择原始值......等等。 Below is a sample of what I would like it to look like without the binding of the pickers.下面是我希望它在没有选择器绑定的情况下看起来的示例。 Thanks谢谢

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")
                }
            }
        }

I'm imagining that you want this to be somewhat dynamic and not hardcoded with if statements.我想象你希望这有点动态,而不是用if语句硬编码。 In order to accomplish that, I setup an enum with the veggie types and then a dictionary that maps the veggie types to their subtypes.为了实现这一点,我设置了一个包含蔬菜类型的enum ,然后是一个将蔬菜类型映射到其子类型的字典。 Those look like:那些看起来像:

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

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

Then, in the view, I did this:然后,在视图中,我这样做了:

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")
        }
    }
}

The selectedVeggie is now typed with VeggieType . selectedVeggie现在使用VeggieType输入。 The selectedSubtype is an optional String that doesn't have an initial value (although you could set one if you want). selectedSubtype是一个没有初始值的可选String (尽管您可以根据需要设置一个)。

The first picker goes through all of the cases of VeggieType .第一个选择器遍历VeggieType的所有案例。 The second one dynamically changes based on the computed property subtypeList which grabs the item from the subTypes dictionary I had made earlier.第二个根据计算的属性subtypeList动态更改,该属性从我之前制作的subTypes字典中获取项目。

The tag item is important -- I had to make the tag as String? tag项很重要——我必须将标记as String? because SwiftUI wants the selection parameter and the tag() to match exactly.因为 SwiftUI 希望selection参数和tag()完全匹配。


Note: you say you're new to Swift, so I'll mention that you had named your view `veggie` -- in Swift, normally types have capital names. 注意:您说您是 Swift 的新手,所以我会提到您已将视图命名为“veggie”——在 Swift 中,通常类型具有大写名称。 I named mine `ContentView`, but you could rename it `VeggieView` or something like that. 我将我的命名为 `ContentView`,但您可以将其重命名为 `VeggieView` 或类似的名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM