SwiftUI 选择器 .onChanged 仅在超过 2 个选择更改时触发

SwiftUI picker .onChanged only firing on 2+ selection changes

我有一个选择器可以更改绑定到视图的对象的属性。更改选择器后,我想更新绑定对象,以便在先前的视图中看到更改。选择器会在每次更改时更新标签,但 .onChanged 修饰符不会在第一次更改后触发。如果更改 2 次或更多次,将触发 .onChanged 主体。

let categories: [String] = ["None", "Produce", "Dairy/Eggs", "Meat", "Breads", "Canned Goods", "Baking", "Frozen", "Bulk", "Snack Foods", "Spices/Seasonings", "Pasta/Rice", "Drinks", "Liquor", "Condiments"]

    //Name of recipe received from previous view
    @Binding var ingredient: Ingredient
   
    
    //ingredient variable that can be updated
    @State var category: String = ""

    var body: some View {
        VStack(alignment: .leading) {
                Text(ingredient.name)
                    .font(.title)
                    .padding(.leading, 5)
                Menu {
                    Picker("picker", selection: $category) {
                        ForEach(categories, id: \.self) {
                            Text([=10=])
                        }
                    }
                    .onChange(of: category, perform: { newValue in
                        print("PICKER CHANGED")
                        ingredient.category = self.category

                    })
                    .labelsHidden()
                    .pickerStyle(InlinePickerStyle())
                    
                } label: {
                    Text(category)
                        .foregroundColor(.black)
                        .padding(5)
                        .labelsHidden()
                        .clipped()
                        .mask(RoundedRectangle(cornerRadius: 20, style: .continuous))
                }
         }
    .onAppear(perform: {self.category = ingredient.category})
}

成分class:

class Ingredient: Identifiable, Hashable{
    static func == (lhs: Ingredient, rhs: Ingredient) -> Bool {
        if (lhs.id == rhs.id) {return true}
        else {return false}
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    public var id = UUID()
    public var name: String = ""
    public var inStock: Bool = false
    public var category: String = ""
    public var keepInStock: Bool = false
}

您是否尝试过在 ForEach 内的 Text 属性 上为选择器设置 tag 修饰符?

Picker("picker", selection: $category) {
    ForEach(categories, id: \.self) {
        Text([=10=]).tag([=10=])
    }
}

这个问题是因为 SwiftUI 不知道这些变化。

Ingredientclass 将其更改为 struct

使其成为 ObservableObject 将变量包装在 @Published 中并更改

@Binding var ingredient: Ingredient

@ObservedObject var ingredient: Ingredient

class是引用类型,struct是值类型。

@State@Binding@Published 查看值类型的更改。

@ObservedObject@StateObject@EnvironmentObject供参考。伴随ObservableObject@Published