美文网首页
SwiftUI-自定义绑定

SwiftUI-自定义绑定

作者: rayChow | 来源:发表于2021-07-21 10:29 被阅读0次

    当我们使用一个Picker或者TextField之类的控件时,我们通常使用@State绑定属性。但这只对简单的属性有用,如果我们需要运行一些逻辑来计算当前值,该怎么去处理呢?那就是自定义绑定。
    首先,我们可以看一下绑定最简单的形式:

    struct ContentView: View {
        @State private var selection = 0
        var body: some View {
            let binding = Binding(
                get: {self.selection},
                set: {self.selection = $0}
            )
            Picker("选择", selection: binding) {
                ForEach(0..<4) { index in
                    Text("item\(index)")
                }
            }
            .pickerStyle(DefaultPickerStyle())
        }
    }
    

    可以看出,改绑定实际上只传递值,它本身不存储或计算任何数据,而只充当我们UI层和正在操作的底层状态值之间的垫片。
    值得注意的是,选择器现在使用的是selection: binding,不需要$绑定符来修饰,因为它已经是一个双向绑定了。

    其次,我们可以使用高级的自定义绑定,不仅仅是传递单个值。例如,假设我们有一个带有三个切换开关的表单:用户是否同意条款和条件、同意隐私政策以及同意接收有关运输的电子邮件。
    我们可以将其表示为三个@State属性:

    @State var agreedToTerms = false
    @State var agreedToPrivacyPolicy = false
    @State var agreedToEmails = false
    

    尽管可以手动切换它们,但我们可以使用自定义绑定一次性完成所有操作。如果这三个布尔值都为真,则此绑定将为真,一旦,则会更新它们,如下所示:

    let agreedToAll = Binding(
        get: {
            self.agreedToTerms && self.agreedToPrivacyPolicy && self.agreedToEmails
        },
        set: {
            self.agreedToTerms = $0
            self.agreedToPrivacyPolicy = $0
            self.agreedToEmails = $0
        }
    )
    
    现在我们可以创建四个切换开关:三个用于单个布尔值,一个控制其他三个同时同意或不同意:
    struct ContentView: View {
        @State var agreedToTerms = false
        @State var agreedToPrivacyPolicy = false
        @State var agreedToEmails = false
    
        var body: some View {
            let agreedToAll = Binding<Bool>(
                get: {
                    self.agreedToTerms && self.agreedToPrivacyPolicy && self.agreedToEmails
                },
                set: {
                    self.agreedToTerms = $0
                    self.agreedToPrivacyPolicy = $0
                    self.agreedToEmails = $0
                }
            )
    
            return VStack {
                Toggle(isOn: $agreedToTerms) {
                    Text("Agree to terms")
                }
    
                Toggle(isOn: $agreedToPrivacyPolicy) {
                    Text("Agree to privacy policy")
                }
    
                Toggle(isOn: $agreedToEmails) {
                    Text("Agree to receive shipping emails")
                }
    
                Toggle(isOn: agreedToAll) {
                    Text("Agree to all")
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:SwiftUI-自定义绑定

          本文链接:https://www.haomeiwen.com/subject/oiadmltx.html