我需要点击+或-按钮并更改数量,问题是使用此代码数量总是重置为零,我不能增加和记住它,我也试过使用这个产品。数量+= 1在每个视图的每个按钮,但在这一点HOME工作,但如果我改变数量从购物车,然后它不会更新它在HOME。如果我代入product。addTo Cart函数中的数量,它告诉我,请帮助我尝试所有的操作符"(变化操作符的左侧是不可变的:'product'是一个'let'常量)"在每个视图中,我想改变数量并在两个视图上更新它我还需要在购物车中只添加一个带有数量的商品,但由于我无法读取数量,所以我添加了更多相同的
我附上了HOME和CART的图片在这里输入图像描述输入图片描述
struct Product: Identifiable,Hashable {
var id = UUID().uuidString
var categoria: ProductType
var codice: String
var descrizione: String = ""
var prezzo: String
var immagine: String = ""
var quantity: Int = 1
}
class SharedDataModel: ObservableObject {
@Published var cartProducts: [Product] = []
func addToCart(product: Product) {
if let index = cartProducts.firstIndex(of: product) {
cartProducts[index].quantity += 1 //it doesn't register the quantity for me and it always resets it to zero
}else {
cartProducts.append(product)
}
}
func removeFromCart(product: Product) {
guard let index = cartProducts.firstIndex(of: product) else {return}
if cartProducts[index].quantity > 1 {
cartProducts[index].quantity -= 1
}else {
cartProducts.remove(at: index)
}
}
struct ProductCardView: View{
@Binding var product: Product
@EnvironmentObject var sharedData: SharedDataModel
var body: some View{
Button (action: {
sharedData.removeFromCart(product: product)
} , label: {
Image(systemName: "minus")
.frame(width: 25, height: 30)
.foregroundColor(.black)
})
Text("(product.quantity-1)") //here i need to read the current quantity
.frame(width: 25, height: 30)
Button(action: {
sharedData.addToCart(product: product)
} , label: {
Image(systemName: "plus")
.frame(width: 25, height: 30)
.foregroundColor(.black)
})
}
}
struct CardView: View{
@Binding var product: Product
@EnvironmentObject var sharedData: SharedDataModel
Button {
sharedData.removeFromCart(product: product)
} label: {
Image(systemName: "minus")
.font(.caption)
.foregroundColor(.white)
.frame(width: 20, height: 20)
.background(Color("Quantity"))
.cornerRadius(4)
}
Text("(product.quantita)")//here i need to read the current quantity
.font(.custom(customFont, size: 14))
.fontWeight(.semibold)
.foregroundColor(.black)
Button {
sharedData.addToCart(product: product)
} label: {
Image(systemName: "plus")
.font(.caption)
.foregroundColor(.white)
.frame(width: 20, height: 20)
.background(Color("Quantity"))
.cornerRadius(4)
}
}
我真的需要你的帮助,我都试过了,非常感谢你
非常感谢您的回复,我试图复制粘贴您的代码添加一个视图,它总是重置金额一旦我改变视图!!
import SwiftUI
struct Product: Identifiable {
let id = UUID()
let title: String
var quantity: Int
}
class StoreModel: ObservableObject {
@Published var cartProducts: [Product] = []
func populateProducts() {
cartProducts = [Product(title: "Product 1", quantity: 0), Product(title: "Product 2", quantity: 0)]
}
func addToCart(_ product: Product) {
guard let index = cartProducts.firstIndex(where: { p in
p.id == product.id
}) else { return }
cartProducts[index].quantity += 1
print(cartProducts)
print(product.quantity)
}
func removeFromCart(_ product: Product) {
guard let index = cartProducts.firstIndex(where: { p in
p.id == product.id
}) else { return }
cartProducts[index].quantity -= 1
}
}
struct ContentView: View {
@EnvironmentObject private var storeModel: StoreModel
var body: some View {
NavigationView {
List(storeModel.cartProducts) { product in //Thread 1: Fatal error: No ObservableObject of type StoreModel found. A View.environmentObject(_:) for StoreModel may be missing as an ancestor of this view
HStack {
Text(product.title)
Button("+") {
storeModel.addToCart(product)
}.buttonStyle(.borderedProminent)
Button("-") {
storeModel.removeFromCart(product)
}.buttonStyle(.borderedProminent)
.tint(.red)
Text("(product.quantity)")
}
}.task {
storeModel.populateProducts()
}
.navigationTitle(Text("Cart"))
.toolbar {
NavigationLink{
Cart()
.environmentObject(StoreModel())
} label: {
Image(systemName: "cart")
}
}
}
}
}
struct Cart: View {
@EnvironmentObject private var storeModel: StoreModel
var body: some View {
List(storeModel.cartProducts) { product in
HStack {
Text(product.title)
Button("+") {
storeModel.addToCart(product)
}.buttonStyle(.borderedProminent)
Button("-") {
storeModel.removeFromCart(product)
}.buttonStyle(.borderedProminent)
.tint(.red)
Text("(product.quantity)")
}
}.task {
storeModel.populateProducts()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(StoreModel())
}
}
我编写了一个小示例来构建类似的场景。我可以更新单个产品的数量。如果有帮助,请告诉我!
import SwiftUI
struct Product: Identifiable {
let id = UUID()
let title: String
var quantity: Int
}
class StoreModel: ObservableObject {
@Published var cartProducts: [Product] = []
func populateProducts() {
cartProducts = [Product(title: "Product 1", quantity: 0), Product(title: "Product 2", quantity: 0)]
}
func addToCart(_ product: Product) {
guard let index = cartProducts.firstIndex(where: { p in
p.id == product.id
}) else { return }
cartProducts[index].quantity += 1
}
func removeFromCart(_ product: Product) {
guard let index = cartProducts.firstIndex(where: { p in
p.id == product.id
}) else { return }
cartProducts[index].quantity -= 1
}
}
struct ContentView: View {
@EnvironmentObject private var storeModel: StoreModel
var body: some View {
List(storeModel.cartProducts) { product in
HStack {
Text(product.title)
Button("+") {
storeModel.addToCart(product)
}.buttonStyle(.borderedProminent)
Button("-") {
storeModel.removeFromCart(product)
}.buttonStyle(.borderedProminent)
.tint(.red)
Text("(product.quantity)")
}
}.task {
storeModel.populateProducts()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(StoreModel())
}
}
如果你在模拟器上运行,那么确保将StoreModel作为环境对象注入到应用程序的根视图中。
@main
struct LearnApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(StoreModel())
}
}
}
我应该能够增加或减少FilteredProducts数组中的数量,但作为一个未填充的数组,我不能这样做,好像它找不到索引
struct Product: Identifiable,Hashable {
var id = UUID().uuidString
var categoria: ProductType
var codice: String
var descrizione: String = ""
var prezzo: String
var immagine: String = ""
var quantita: Int = 0
}
enum ProductType: String,CaseIterable{
case Croci = "Croci"
case Medaglie = "Medaglie"
case Cuori = "Cuori"
case Stelle = "Stelle"
}
class HomeViewModel: ObservableObject {
@Published var productType: ProductType = .Croci
@Published var products: [Product] = [Product(categoria: .Croci, codice: "P20-10A", prezzo: "10€",immagine: "P20-10A"),
Product(categoria: .Croci, codice: "P20-10N", prezzo: "11€",immagine: "P20-10N"),]
@Published var filteredProducts: [Product] = []
init(){
filterProductByType()
searchCancellable = $searchText.removeDuplicates()
.debounce(for: 0.5, scheduler: RunLoop.main)
.sink(receiveValue: { str in
if str != ""{
self.filterProductBySearch()
}
else{
self.searchedProducts = nil
}
})
}
func incrementQuantityFiltered(_ product: Product) {
guard let index = products.firstIndex(where: { p in
p.id == product.id
}) else { return }
products[index].quantita += 1
}
func decrementQuantityFiltered(_ product: Product) {
guard let index = products.firstIndex(where: { p in
p.id == product.id
}) else { return }
products[index].quantita -= 1
}
func filterProductByType(){
// Filtering Product By Product Type...
DispatchQueue.global(qos: .userInteractive).async {
let results = self.products
// Since it will require more memory so were using lazy to perform more...
.lazy
.filter { product in
return product.categoria == self.productType
}
// Limiting result...
DispatchQueue.main.async {
self.filteredProducts = results.compactMap({ product in
return product
})
}
}
}
}
struct Home: View {
@EnvironmentObject var sharedData: SharedDataModel
@StateObject var homeData: HomeViewModel = HomeViewModel()
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
ForEach($homeData.filteredProducts){$product in
ProductCardView(product: $product,homeData: HomeViewModel())
}
}
struct ProductCardView: View{
@Binding var product: Product
@EnvironmentObject var sharedData: SharedDataModel
@ObservedObject var homeData: HomeViewModel
var body: some View{
HStack (spacing: 0){
Text(product.codice)
Text(product.prezzo)
}
Button (action: {
homeData.decrementQuantityFiltered(product)
} , label: {
Image(systemName: "minus")
})
Text("(product.quantita)")
Button(action: {
homeData.incrementQuantityFiltered(product)
} , label: {
Image(systemName: "plus")
})