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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:15:07