代码之家  ›  专栏  ›  技术社区  ›  ra9r

解释绑定的这个有用扩展是如何在SwiftUI中工作的

  •  0
  • ra9r  · 技术社区  · 2 年前

    我最近发现了这种延伸 Binding 我很难理解它是如何工作的。

    extension Binding where Value == Bool {
        
        init<T>(value: Binding<T?>) {
            self.init {
                value.wrappedValue != nil
            } 
            set: { newValue in
                if !newValue {
                    value.wrappedValue = nil
                }
            }
        }
        
    }
    

    我理解它的目的。它的设计使您能够使用 结合 对于作为触发器的可选值 .alert(...) .sheet(...)

    例如:

    struct ExampleView : View {
        
        @State var message: String? = nil
        @State var showIt: Bool = false
        
        var body: some View {
            Button("Show Message") {
                message = "Some kind of message"
            }.alert("Alert!", isPresented: Binding(value: $message)) { // <---- used here
                Text(message!)
            }
        }
    }
    

    我从未见过 self.init { ... } 初始化器内部。我也对使用感到困惑 set: { ... } 在初始值设定项中。请帮我理解这些语言语义。

    1 回复  |  直到 2 年前
        1
  •  1
  •   Sweeper    2 年前

    扩展中的初始化程序必须调用现有的初始化程序,或者为 self .否则怎么初始化 Binding 毕竟

    扩展中声明的初始化程序正在调用 this existing initialiser 属于 结合 ,它接受名为 get set 。请注意 设置 不是某些特殊语法的一部分,它只是一个参数名称。

    呼叫 self.init 正在使用尾随闭包语法,如所述 here 在语言参考中。此语法允许您省略第一个参数的参数标签。我有答案 here 更详细地说。

    在SwiftUI中,无论何时初始化视图,都可以看到这种语法,例如:

    Button {
        // do something
    } label: {
        Text("Foo")
    }
    

    您正在呼叫 Button.init 这需要一个 action label 。请注意 action: 参数标签被省略。

    最后,虽然此扩展对于 alert s sheet 具有采用 item: Binding<Item?> ,所以您不需要将此扩展用于 床单 s