'What is the difference in declaring a Binding property in SwiftUI?

What is the difference declaring a binding property in SwiftUI i.e

@Binding var foo: String

versus

var foo: Binding<String>


Solution 1:[1]

If you do @Binding var foo: String, then you sort of simultaneously declare three things:

  • foo, which is a String,
  • _foo, which is a Binding<String> (this is private)
  • $foo, which is a Binding<String>

The relationship between foo, _foo and $foo is:

// this is basically how property wrappers are implemented under the hood
private var _foo: Binding<String>
var foo: String {
    get { _foo.wrappedValue }
    set { _foo.wrappedValue = newValue } 
}
var $foo: Binding<String> {
    _foo.projectedValue
}

See also the SE proposal for more details.


If you do var foo: Binding<String>, you just get foo, which is a Binding<String>. There's no such thing as $foo and _foo.

Since Binding<String> is marked with @dynamicMemberLookup, you are still able to use String's members on this foo, so it may look like foo is a String on first sight, but it is still of type Binding<String> as far as the type system is concerned. For example, you cannot use it in places where a String normally would work:

Text(foo) // error

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1