我来自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)
}
}
}
1条答案
按热度按时间f1tvaqid1#
Product应该是结构,
@ObservedObject
应该是@EnvironmentObject
,并在App结构中使用.environmentObject(GroceryList.shared)
。