如果我们需要自定义 init 方法,在 init 中直接赋值 @Binding 会失败。
赋值失败的原因是 @Binding 是一个 property wrapper,有 get 和 set 方法。他的 set 方法中存储的值是 Binding,但是还有 get 方法。因此 Binding 并不直接等于 @Binding。
我们可以通过把变量 @Binding 类型改为 Binding 来体会这两者的区别。
// Binding<T>
struct BindingInit: View {
var name: Binding<String>
init(name: Binding<String>) {
self.name = name
}
var body: some View {
Text(name.wrappedValue)
TextField("name", text: name)
.padding()
.onAppear {
name.wrappedValue = "New"
}
}
}
// @Binding
struct BindingInitNormal: View {
@Binding var name: String
var body: some View {
Text(name)
TextField("name", text: $name)
.padding()
.onAppear {
name = "New"
}
}
}
如果直接使用 Binding 作为属性,在对值的读取和设置都需要显式的通过 wrappedValue 调用。在 View 的操作中就会稍显繁琐。
那么如何赋值呢?
Property wrapper 默认生成的真实变量名是在名称前加下划线(_)。因此我们在赋值的时候直接赋值给真实的存储变量就可以了。
struct BindingInitNormal: View {
@Binding var name: String
init(name: Binding<String>) {
self._name = name
}
}