ios 除非列表刷新,否则计算值不会在视图中更新?(SwiftUI)

ut6juiuv  于 2023-06-07  发布在  iOS
关注(0)|答案(1)|浏览(165)

我来自C#背景,我是SwiftUI的新手。我正在尝试创建一个应用程序,可以帮助我跟踪我的杂货店购物。我想显示一个带有标题的列表和一堆我以后会在商店购买的产品。
我将产品作为GroceryList类中的数组收集起来。我可以添加新产品,删除产品,在列表中移动产品。
当我使用GroceryList类中的一个函数显示杂货清单中购买的产品数量时,我的问题出现了:ProductAcquiredAmount()。只有当我在列表中添加、删除或移动产品时,计算值才会更新。我希望每次检查产品时,顶部的计算值都会更新。

产品类别:

class Product: ObservableObject, Identifiable {
    var id = UUID()
    @Published var name: String
    @Published var acquired: Bool
    
    init(name: String, acquired: Bool) {
        self.name = name
        self.acquired = acquired
    }
}

GroceryList类:

class GroceryList: ObservableObject, Identifiable {
    var id = UUID()
    @Published var date: String
    @Published var products: [Product]
    
    init(date: String, products: [Product]) {
        self.date = date
        self.products = products
    }
    
    func ProductAcquiredAmount() -> Int {
        var productAcquiredAmount = 0
        for product in self.products {
            if product.acquired {
                productAcquiredAmount = productAcquiredAmount + 1
            }
        }
        return productAcquiredAmount
    }
}

和视图:

struct GroceryMainView: View {
    
    @ObservedObject var grocList: GroceryList = GroceryList(date: "Current list", products: [Product(name: "Potato", acquired: false), Product(name: "Bread", acquired: true), Product(name: "Coffee", acquired: false)])
    
    @State private var hideAcquiredProducts = false
    
    var body: some View {
        NavigationView {
            List {
                Section(content: {
                    ForEach($grocList.products) { $product in
                        if hideAcquiredProducts == false || (hideAcquiredProducts && product.acquired == false) {
                            ProductRow(product: product)
                        }
                    }.onDelete(perform: { indexSet in
                        grocList.products.remove(atOffsets: indexSet)
                    }).onMove(perform: { indices, newOffset in
                        grocList.products.move(fromOffsets: indices, toOffset: newOffset)
                    })
                    NewProductRow(groceryList: grocList)
                }, header: {
                    HStack {
                        Text(grocList.date)
                            .font(.title3)
                            .foregroundColor(.accentColor)
                        Spacer()
                        Text("\(grocList.ProductAcquiredAmount()) / \(grocList.products.count)")
                            .font(.title3)
                            .foregroundColor(.accentColor)
                    }
                })
            }
            .listStyle(GroupedListStyle())
            .navigationTitle("Grocery Lists")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
                
                ToolbarItem(placement: .bottomBar) {
                    Toggle(isOn: $hideAcquiredProducts, label: {
                        Text("Focus Mode")
                    }).toggleStyle(.switch)
                }
            }
        }
    }
}

struct ProductRow: View {
    @ObservedObject var product: Product
    @State var productName: String = ""

    var body: some View {
        HStack {
            Button(action: {
                if self.product.acquired {
                    self.product.acquired = false
                } else {
                    self.product.acquired = true
                }
            }, label: {
                Image(systemName: product.acquired ? "checkmark.square" : "square")
            })
            if product.acquired {
                TextField("", text: $product.name)
                    .strikethrough()
                    .foregroundColor(.gray)
            } else {
                TextField("", text: $product.name)
            }
        }
    }
}

struct NewProductRow: View {
    @ObservedObject var groceryList: GroceryList
    @State var newProductName = ""
    
    var body: some View {
        HStack {
            Button(action: {
                let newProduct = Product(name: newProductName, acquired: false)
                newProductName = ""
                self.groceryList.products.append(newProduct)
            }, label: {
                Image(systemName: "plus")
            })
            TextField("...", text: $newProductName)
        }
    }
}
f1tvaqid

f1tvaqid1#

Product应该是结构,@ObservedObject应该是@EnvironmentObject,并在App结构中使用.environmentObject(GroceryList.shared)

相关问题