SwiftUI 常用 Property Wrappers 之 Binding

🧠🔋


在 SwiftUI 中,Binding 是一种通过引用传递的属性包装器,用于在视图之间建立双向绑定。通过使用 Binding,我们可以将属性与视图的状态关联起来,使得属性的变化能够自动反映在视图上,同时用户对视图的操作也能更新属性的值。

下面是一个简单的示例,演示了如何使用 Binding 在 SwiftUI 中实现双向绑定:

struct ContentView: View {
    @State private var name = ""
    
    var body: some View {
        VStack {
            TextField("请输入姓名", text: $name)
            Text("你好,\(name)!")
        }
        .padding()
    }
}

在上述代码中,我们通过 @State 属性包装器将 name 属性声明为可变状态。然后,在 TextField 中使用 text 参数时,我们将 $name 传递给它,表示我们希望将 name 属性与输入框的文本内容进行绑定。这样,当用户在输入框中输入内容时,name 属性的值将自动更新,并在 Text 视图中显示出来。

在前面我们学习 @State 的时候已经看到了通过第一个 View 的 number 更新第二个View,那如果我们想点击第二个 View 来更新父 View 呢?这就用到了我们的 @Binding。

从字面意思我们可以知道 Binding 是捆绑在一起的意思,捆绑在一起,那一个更新必然
也会更新另外一个。

struct BindingView: View {
    @State var number: Int = 0
    @State var show = false
    var body: some View {
        Button {
            show.toggle()
        } label: {
            Text("Number is: \(number)")
        }.sheet(isPresented: $show) {
            DetailView(number: $number)
        }
    }
    
    struct DetailView: View {
        @Binding var number: Int
        var body: some View {
            Button {
                number += 1
            } label: {
                Text("Number is: \(number)")
            }

        }
    }
}

可以看到当我们在 DetailView 里设置了 @Binding 的时候,在初始化里使用 $number 表示 Binding,也可以看到我们的.sheet 里 isPresented 也是 Binding, 所以当我们也可以在新页面设置一个 show 的 Bool 值来 Binding 前面页面的 isPresented,在新页面设置 show 为 false 来关闭页面,和我们之后要学习的 @Environment(.presentationMode) 是一样的效果。在某些时候,我们可能不需要传入一个 Binding 的值,可能是固定的值也可以,可以使用 .constant(value),传入的就是一个固定值,不能改变。

通过使用 Binding,我们可以轻松实现属性与视图之间的双向绑定,使得 SwiftUI 开发更加便捷和灵活。Binding 是 SwiftUI 中非常常用的 Property Wrappers 之一,你可以根据具体的需求将其应用于不同的场景。