You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现每个产品对应的TextField值独立唯一?

问题解决思路

核心问题是单个partsUsedPerProduct整数无法对应多个产品的独立数值,所有TextField绑定到同一个变量,必然同步变化。需要从数据模型和视图绑定两方面修改:

1. 修改Part数据模型

把单个Int类型的partsUsedPerProduct改为字典类型,用Product的唯一ID作为键,存储对应产品的使用量:

import SwiftData
import PhotosUI

@Model
class Part {
    var partNumber: String
    var name: String
    var rev: String
    var stock: Int
    var cost: Double
    // 改为字典:key是Product的UUID字符串,value是对应产品的使用量
    var partsUsedPerProduct: [String: Int]
    var partImage: Data?
    
    init(partNumber: String, name: String, rev: String, stock: Int, cost: Double, partsUsedPerProduct: [String: Int], partImage: Data?) {
        self.partNumber = partNumber
        self.name = name
        self.rev = rev
        self.stock = stock
        self.cost = cost
        self.partsUsedPerProduct = partsUsedPerProduct
        self.partImage = partImage
    }
    
    // 新增便捷初始化方法,默认给所有传入的Product设置初始值0
    convenience init(partNumber: String, name: String, rev: String, stock: Int, cost: Double, products: [Product], partImage: Data?) {
        var initialDict = [String: Int]()
        products.forEach { product in
            initialDict[product.id.uuidString] = 0
        }
        self.init(partNumber: partNumber, name: name, rev: rev, stock: stock, cost: cost, partsUsedPerProduct: initialDict, partImage: partImage)
    }
}

2. 调整AddPartSheet视图

  • 初始化Part时,用新增的便捷方法给每个Product设置初始使用量0
  • 在ForEach中,绑定到字典对应Product的ID值,处理可选绑定(因为字典值可能为nil)

修改后的AddPartSheet关键部分:

struct AddPartSheet: View {
    // 省略其他状态...
    @State var part: Part
    @Query var products: [Product]
    @Environment(\.modelContext) private var context
    @Environment(\.dismiss) private var dismiss

    // 初始化新增Part的实例
    init() {
        self._products = Query()
        self._part = State(initialValue: Part(partNumber: "", name: "", rev: "", stock: 0, cost: 0, products: [], partImage: nil))
    }

    // 编辑已有Part时的初始化
    init(editing part: Part) {
        self._products = Query()
        self._part = State(initialValue: part)
        // 补全新增Product的初始值(如果有)
        products.forEach { product in
            if part.partsUsedPerProduct[product.id.uuidString] == nil {
                part.partsUsedPerProduct[product.id.uuidString] = 0
            }
        }
    }

    var body: some View {
        NavigationStack {
            Form {
                // 省略其他Section...
                Section ("Parts Used per Product"){
                    ForEach(products) { product in
                        HStack(alignment: .firstTextBaseline){
                            Text(product.name)
                            Spacer()
                            // 绑定到对应ProductID的字典值,处理可选情况
                            TextField("\(part.name) used per \(product.name)", value: Binding(
                                get: { part.partsUsedPerProduct[product.id.uuidString] ?? 0 },
                                set: { part.partsUsedPerProduct[product.id.uuidString] = $0 }
                            ), format: .number)
                                .keyboardType(.phonePad)
                                .focused($Focus)
                        }
                    }
                }
            }
            .navigationTitle("New Part")
            .toolbar {
                ToolbarItemGroup(placement: .topBarTrailing) {
                    Button("Save") {
                        context.insert(part)
                        dismiss()
                    }
                }
                // 省略其他Toolbar内容...
            }
        }
    }
}

3. 额外说明

  • 用Product的id作为字典键,比用数组索引更可靠,避免数组顺序变化导致对应关系错误
  • 绑定字典值时,用Binding(get:set:)包装,处理字典值可能为nil的情况,默认返回0
  • 如果是编辑已有Part,需要确保字典包含所有当前Product的ID,若有新增Product,可在初始化时补全初始值

内容的提问来源于stack exchange,提问作者ApplePro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:32:43