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

问题描述 投票:0回答:1

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

问题出在这一行代码上..

 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)
                    }
                }
            }
    }

}

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

  import SwiftUI

struct OrderView: View {
    @EnvironmentObject var order: Order
    @State private var quantity: String = ""

    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 {

                                Text("Add Item: \(Image(systemName: "plus.circle"))")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .trailing)
                                Spacer()

                                Text("Remove Item: \(Image(systemName: "minus.circle"))")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .trailing)

                                Spacer()
                                HStack {
                                    Text("Move to Trash:")
                                        .font(.subheadline)
                                        .bold()
                                        .frame(maxWidth: .infinity, alignment: .trailing)
                                    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()
                                Text("Quantity:")
                                    .font(.subheadline)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                    .bold()
                                TextField("amount", text: $quantity)
                                    .border(.green)
                                    .frame(maxHeight: 10, alignment: .leading)
                            }
                            HStack {
                                Text("Price: £\(item.price)")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                Text("Total:")
                                    .font(.subheadline)
                                    .bold()
                                    .frame(maxWidth: .infinity, alignment: .leading)
                            }
                        }
                    }
                }
                Section {
                    NavigationLink("Place Order") {
                    }
                }
            }
            .navigationTitle("Order")
        }
    }
}

这是截图..

ios swiftui binding textfield shopping-cart
1个回答
0
投票

您的订单中有重复的数据(产品),但只有一个

$quantity
,它不以任何方式链接到产品。

我还建议

TextField
不是最好使用的 UI 元素;您需要负责验证/解析内容以确保它是一个数字。

有一个更简单的控件可用 - A

Stepper
- 如果您使用
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")
        }
    }
}

从设计的角度来看,当图标清晰时,不需要像“移至垃圾箱”这样的文字描述。

© www.soinside.com 2019 - 2024. All rights reserved.