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())
注意点
- 确保
User结构体里的name、email、sex都是可变属性(用var定义,不是let),否则无法修改。 - 因为
employee是@Binding,修改它的属性会直接同步到上级视图的数据源,所以点击更新按钮时直接传employee就行。
备注:内容来源于stack exchange,提问作者Robinson Gonzalez
相关产品推荐
相关产品推荐

