SwiftUI如何实现TextField绑定非类Struct模型的属性
问题根因
- 你的
Field结构体的key属性定义为let常量,本身就不可修改,首先要改成可变属性 ForEach直接遍历数组获得的是元素的拷贝值,不是可读写的绑定类型,而TextField的text参数要求传入Binding<String>类型,传普通String值必然会报错@ObservableObject只能用于遵守ObservableObject协议的类,结构体不适用,该方案本身就不匹配你的场景
完整解决方案代码
首先修改结构体属性为可修改:
public struct Field: Codable, Hashable { // 把let改为var支持属性修改 var key: String enum CodingKeys: String, CodingKey { case key } }
然后修改视图部分的ForEach写法,直接遍历数组的绑定:
let decodableJSON = """ { "key": "" } """ let settableInit: Field = try! JSONDecoder().decode(Field.self, from: decodableJSON.data(using: .utf8)!) struct Test_view: View { @State var settableFields: [Field] = [settableInit] var body: some View { // 加$前缀获取数组的绑定类型,遍历后每个元素都是Binding<Field> ForEach($settableFields, id: \.key) { $settableField in TextField("Key", text: $settableField.key) } // 增操作示例,可直接操作原数组 Button("新增字段") { settableFields.append(Field(key: "")) } } }
核心逻辑说明
- 对
@State修饰的数组使用$前缀,可以获得数组的Binding类型,遍历该绑定类型得到的每个元素都是对应数组元素的读写绑定 - 遍历闭包中用
$settableField接收绑定类型的元素,再通过$settableField.key就能拿到属性的绑定,直接传入TextField即可正常修改 - 如果需要支持删除操作,搭配
List和onDelete修饰符即可实现,逻辑和普通数组操作完全一致,不需要额外调整结构体定义
内容的提问来源于stack exchange,提问作者norwegiandev
相关产品推荐
相关产品推荐

