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

SwiftUI中无需创建额外变量即可读写结构体内部属性的实现方式咨询

SwiftUI中无需创建额外变量即可读写结构体内部属性的实现方式咨询

当然可以实现啦!你完全不用额外定义那些@State变量,直接绑定到employee的内部属性就搞定了,不过因为User是值类型的结构体,我们需要处理一下可选属性的绑定问题,下面给你一步步梳理方案:

核心思路

你的employee已经是@Binding修饰的变量了,我们可以直接基于它的属性创建绑定,不用额外存一份副本到@State里。针对可选字符串属性,我们可以通过自定义Binding来把可选值转换成TextField需要的非可选字符串绑定。

修改后的完整代码

struct UpdateEmployee: View {
    @ObservedObject var employeesViewModel : EmployeesViewModel
    @Binding var employee: User

    var body: some View {
        VStack{
            // 直接绑定employee.name,处理可选值
            VStack{
                Text("Nombre")
                    .foregroundColor(Color.black)
                TextField("Nombre", text: Binding(
                    get: { employee.name ?? "" },
                    set: { employee.name = $0 }
                ))
                .frame(maxHeight: 45)
                .border(Color.gray, width: 0.5)
                .padding([.horizontal, .bottom, .top], 30)
            }

            // 绑定employee.email
            VStack{
                Text("Correo")
                    .foregroundColor(Color.black)
                TextField("Correo", text: Binding(
                    get: { employee.email ?? "" },
                    set: { employee.email = $0 }
                ))
                .frame(maxHeight: 45)
                .border(Color.gray, width: 0.5)
                .padding([.horizontal, .bottom, .top], 30)
            }

            // 绑定employee.sex
            VStack{
                Text("Genero")
                    .foregroundColor(Color.black)
                TextField("Genero", text: Binding(
                    get: { employee.sex ?? "" },
                    set: { employee.sex = $0 }
                ))
                .frame(maxHeight: 45)
                .border(Color.gray, width: 0.5)
                .padding([.horizontal, .bottom, .top], 30)
            }

            Button {
                print(employee.id)
                // 这里不用再手动赋值了,TextField已经直接修改了employee的属性
                employeesViewModel.updateEmployee(employee: employee)
            } label: {
                Text("Actualizar")
            }

            Spacer()
        }
        // 也不需要onAppear来初始化变量了,绑定会直接读取employee的当前值
    }
}

额外优化小技巧

如果你的项目里经常需要处理可选字符串的绑定,可以写个扩展来简化代码:

extension Binding where Value == String? {
    func defaultEmpty() -> Binding<String> {
        Binding<String>(
            get: { self.wrappedValue ?? "" },
            set: { self.wrappedValue = $0 }
        )
    }
}

这样TextField的代码就可以简化成:

TextField("Nombre", text: $employee.name.defaultEmpty())

注意点

  1. 确保User结构体里的name、email、sex都是可变属性(用var定义,不是let),否则无法修改。
  2. 因为employee是@Binding,修改它的属性会直接同步到上级视图的数据源,所以点击更新按钮时直接传employee就行。

备注:内容来源于stack exchange,提问作者Robinson Gonzalez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 13:04:06