在 Swift UI 中使用 TextFiled 同时更新两条记录

Using TextFiled in Swift UI update two record same time

提问人:Nus 提问时间:11/1/2023 最后编辑:Nus 更新时间:11/1/2023 访问量:42

问:

我使用Textfiled,我可以在其中输入产品的数量。我正在使用$Binding属性包装器。这是一个购物车视图(Order view)。问题是当我输入值时,它也会更新两个购物车数量。当我在TextField上编辑数量时,下一条记录不应该更新。我在 TextField 和 Quantity 文本之间也有间距问题。

问题出在这条行代码上。

 HStack(spacing: 20) {
                                Text("Name: \(item.title)")
                                    .font(.subheadline)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .bold()
                                Text("Quantity:")
                                    .font(.subheadline)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .bold()
                                TextField("amount", text: $quantity)
                                    .border(.green)
                                    .frame(maxHeight: 10, alignment: .leading)
                            }

这是产品视图的单元格。

import SwiftUI

struct ProductListViewCell: View {

        let productData: Product
        @EnvironmentObject var order: Order
    
        var body: some View {
            HStack {
                if let url = URL(string: productData.thumbnail) {
                    ProductAsyncImageView(url: url)
                        .frame(width: 150, height: 150)
                        .mask(RoundedRectangle(cornerRadius: 16))
                }
                VStack(alignment: .leading,spacing: 5) {
                    Text("Name: " +  (productData.title))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .font(.headline)
    
                    Text("Description: " + (productData.description))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .multilineTextAlignment(.leading)
    
                    Text("Price: £" + String(productData.price))
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .font(.subheadline)
    
                    Button {
                        order.add(item: productData)
    
                    } label: {
                        HStack {
                            Image(systemName: "cart.badge.plus")
    
                            Text("Add to Cart")
                                .fontWeight(.semibold)
                        }
                        .foregroundColor(.white)
                        .frame(width: 150 , height: 40)
    
                    }
                    .background(Color(.systemBlue))
                    .cornerRadius(10)
                }
            }
        }
    }

这是产品列表的代码。

import SwiftUI

struct ProductListView: View {
    
    var body: some View {

        NavigationStack {
            VStack {
                
                    if viewModel.productLists.count > 0 && !viewModel.refreshing {

                        List(viewModel.productList, id: \.self) { product in
                            ProductListViewCell(productData: product)

                        } .listStyle(.grouped)
                    }
                }
            }
    }

}

这是我的订单查看代码..

      struct OrderView: View {
    @EnvironmentObject var order: Order
    @State private var quantity: Int = 1

    var body: some View {
        NavigationStack {
            List {
                Section {
                    ForEach(order.product) { item in
                        Section {
                            HStack {
                                Text("Description")
                                    .foregroundColor(.blue)
                                    .bold()
                                Spacer()
                                Text("Action")
                                    .foregroundColor(.blue)
                                    .bold()
                            }
                        }

                        HStack {
                            if let url = URL(string: item.thumbnail) {
                                ProductAsyncImageView(url: url)
                                    .frame(width: 90, height: 90)
                                    .padding(.bottom, -10)
                                    .clipShape(Circle())
                            }
                            Spacer()

                            VStack {
                                HStack {
                                    Stepper {
                                        Text("\(Image(systemName: "multiply"))\(quantity)")

                                    }
                                onIncrement: {
                                    quantity+=1

                                }
                                onDecrement: {
                                    if quantity > 1 {
                                        quantity -= 1
                                    }
                                }

                                    Image(systemName: "trash")
                                        .foregroundColor(Color(hue: 1.0, saturation: 0.89, brightness: 0.835))
                                        .onTapGesture {
                                            order.remove(item: item)
                                        }
                                }
                            }
                            Spacer()
                        }

                        VStack {
                            HStack(spacing: 20) {
                                Text("Name: \(item.title)")
                                    .font(.subheadline)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .bold()

                            }
                            HStack {
                                Text("Price: £\(item.price)")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                Text("Sub Total: £\(quantity * item.price)")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                        }
                    }
                }
                Section {
                    NavigationLink("Place Order") {
                    }
                }
            }
            .navigationTitle("Order")
        }
    }
}

这是屏幕截图..

enter image description here

iOS SwiftUI 绑定 TextField 购物车

评论


答:

1赞 Paulw11 11/1/2023 #1

您的订单中有重复的数据(产品),但只有一个 ,它没有以任何方式链接到产品。$quantity

我还建议 a 不是最好的 UI 元素;您需要注意验证/解析内容以确保它是一个数字。TextField

有一个更简单的控件可用 - 步进器 - 如果您使用 ,您可以消除已添加的 +/- 按钮,并且无需担心输入无效值。Stepper

像这样的东西——

struct OrderView: View {
    @EnvironmentObject var order: Order

    var body: some View {
        NavigationStack {
            List {
                Section {
                    ForEach(order.product) { item in
                        Section {
                            HStack {
                                Text("Description")
                                    .foregroundColor(.blue)
                                    .bold()
                                Spacer()
                                Text("Action")
                                    .foregroundColor(.blue)
                                    .bold()
                            }
                        }

                        HStack {
                            if let url = URL(string: item.thumbnail) {
                                ProductAsyncImageView(url: url)
                                    .frame(width: 90, height: 90)
                                    .padding(.bottom, -10)
                                    .clipShape(Circle())
                            }
                            Spacer()

                                
                                HStack {
                                    Stepper {
                                        Text("\(item.quantity)")
                                    }
                                    onIncrement: {
                                        item.quantity+=1
                                    }
                                    onDecrement: {
                                        if item.quantity > 1 {
                                           item.quantity -= 1
                                    }
                                    Image(systemName: "trash")
                                        .foregroundColor(Color(hue: 1.0, saturation: 0.89, brightness: 0.835))
                                        .onTapGesture {
                                            order.remove(item: item)
                                        }
                                }
                            }
                            Spacer()
           

                        VStack {
                            HStack(spacing: 20) {
                                Text("Name: \(item.title)")
                                    .font(.subheadline)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .bold()
                            }
                            HStack {
                                Text("Price: £\(item.price)")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                Text("Total: £\(item.quantity * item.price)")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                        }
                    }
                }
                Section {
                    NavigationLink("Place Order") {
                    }
                }
            }
            .navigationTitle("Order")
        }
    }
}

从设计的角度来看,当图标清晰时,不需要像“移至废纸篓”这样的文本描述。

评论

0赞 Nus 11/1/2023
感谢您的回答,但是当我尝试更新项目的质量时,使用步进器,记录的其余部分也会更新。我只想更新特定的行。
0赞 Nus 11/1/2023
基本上,当我使用步进器增加或减少项目时。它还会增加或减少订单视图中的其余项目数量
0赞 Nus 11/1/2023
正如您在屏幕上看到的,当您单击步进器 + 或 - 时,购物车记录的其余部分会自动更新
0赞 Paulw11 11/1/2023
因为您仍然有一个数量 - - 请注意,在我的回答中,是 - 您需要更新与订单中每个产品关联的数量。@State private var quantity: Int = 1quantityitem.quantity
0赞 Paulw11 11/1/2023
您需要将此答案用于您之前的问题。