如何存储多个选择器的选择?

How to store selection of multiple Pickers?

我有 4 只狗 - 由 4 个 Pickers 代表 - 每只狗都有最喜欢的食物。如何存储每个 Picker 的选择?我尝试将它存储在字典中,但是当单击其中一种食物时,没有任何内容被选中,选择器视图也没有被关闭。

import SwiftUI
import OrderedCollections

enum Dog : String, CaseIterable, Identifiable {
    var id: Self { self }
    case Anton, Ben, Charlie, Didi
}

struct MainConstants {
    let treats : OrderedDictionary <String, Int> = [
        "Bone" : 123,
        "Sausage" : 456,
        "Cookies" : 789
    ]
}


struct FavouriteTreatsView: View {
    
    let constants = MainConstants()
    
    @State var favouriteTreats : [Dog : String] = [:]
    
    var body: some View {
        NavigationView {
            Form {
                ForEach (Dog.allCases) {dog in
                    Picker(dog.rawValue ,selection: $favouriteTreats[dog]) {
                        ForEach (constants.treats.keys, id: \.self) {treat in
                            Text(treat)
                        }
                    }
                }
            }
        }
    }
}

struct FavoriteTreatsView_Previews: PreviewProvider {
    static var previews: some View {
        FavouriteTreatsView()
    }
}

我不知道如何治疗狗,但是下面的例子对狮子很有效...

首先,您可以为每个单独的选择器提供一个专用视图 - 该视图会将每只狮子的款待存储在 @State 变量中。您使用 .id() 修饰符来告诉选择器需要存储什么值。

该视图还将有一个 @Binding 接收字典的 var,用于存储在右侧狮子上选择的款待。

在该选择器视图中,您可以监听食物的变化:选择食物后,您将该值存储在与绑定变量一起传递的字典中。

所以,假设它们是狮子,这是选择器视图:

struct TreatMe: View {
    let constants = MainConstants()

    // treat for a single Lion
    @State private var treat = ""
    
    // The dictionary that will be updated after the treat is selected
    @Binding var favouriteTreats: [Lion: String]
    
    // the Lion that will receive the treat
    let lion: Lion
    
    var body: some View {
        Picker(lion.rawValue ,selection: $treat) {
            ForEach (constants.treats.keys, id: \.self) {treat in
                Text(treat)
                
                    // This will ensure the right value is stored
                    .id(treat)
            }
        }
        
        // Listen to changes in the treat, then store it in the dictionary
        .onChange(of: treat) { value in
            favouriteTreats[lion] = value
        }
    }
}

您从 FavouriteTreatsView:

调用它
struct FavouriteTreatsView: View {
    
    @State var favouriteTreats : [Lion : String] = [:]
    
    var body: some View {
        NavigationView {
            Form {
                ForEach (Lion.allCases) {lion in
                    
                    // Pass the variables
                    TreatMe(favouriteTreats: $favouriteTreats, lion: lion)
                }
            }
        }
    }
}