I have a picker that will change an attribute of an object that is bound to the view. When the picker is changed I want to update the bound object so the change is apparent in the previous view. The picker updates the label on each change but the .onChanged modifier does't fire after the first change. If changed 2 or more times the .onChanged body fires.
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($0)
}
}
.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})
}
Ingredient 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
}
$ingredient.categoryas thePickerselection@State var categoryit isn't needed. By connecting it all through$ingredient.categorywhen you persist to a database it will all get updated. It is best to have aSaveButton.onAppear,onChange, andonDismissseems to be unreliable. You can try but I would not count on themclasschange it to astructOR make it anObservableObjectwrap the variables in@Publishedand change@Binding var ingredient: Ingredientto@ObservedObject var ingredient: Ingredient