如何实现每个产品对应的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
相关产品推荐
相关产品推荐

