Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Explain how this useful extension of Binding works in SwiftUI

I recently came across this extention to Binding and I am having trouble understanding how it works.

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

Its purpose I understand. It’s designed to enable you to use a Binding for an Optional value as the trigger for .alert(...) or .sheet(...).

For example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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!)
        }
    }
}

I’ve never seen the use of self.init { ... } inside of an initializer. I’m also confused by the use of set: { ... } in the initializer. Please help me understand these language semantics.

>Solution :

The initialiser in the extension must call an existing initialiser, or assign something to self. How else is it going to initialiser a Binding, after all?

The initialiser declared in the extension is calling this existing initialiser of Binding, which takes closure parameters called get and set. Note that set isn’t part of some special syntax – it’s just a parameter name.

The call to self.init is using the trailing closure syntax, described here in the language reference. This syntax allows you to omit the parameter label of the first parameter. I have an answer here that goes into more detail.

You see this syntax everywhere in SwiftUI, whenever you initialise views, like:

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

You are calling the Button.init that takes an action and a label. Notice that the action: parameter label is omitted.

Finally, while this extension is useful for alerts, sheet has a version that takes in an item: Binding<Item?>, so you don’t need to use this extension for sheets.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading