Search code examples
swiftswiftuiproperty-wrapper

Difference between @Binding and Binding<Type> in Swift


I understand that @Binding is a property wrapper and I believe that Binding<Type> is a form of type casting but what is the difference in practical terms?

For example declaring a var like:

@Binding
var hidden: Bool

versus

var hidden: Binding<Bool>

Solution

  • You're correct that @Binding is a property wrapper. More specifically, it's a DynamicProperty, which means that it has the ability to notify its parent View to trigger a render when its value changes.

    @Binding does this while maintaining a fairly transparent interface to the underlying Bool. For example, in a View where you had @Binding var hidden: Bool defined as a property, you could write hidden = false or Text(hidden ? "hidden" : "visible"), just as if hidden were a regular Bool. If you want to get access to the underlying Binding<Bool>, you can use $:

    $hidden //<-- Binding<Bool>
    

    In your second example, Binding<Bool> is not "type casting", but rather "type annotation" -- by writing var hidden: Binding<Bool>, you're telling the compiler that hidden is Binding<Bool>. Because it's Binding<Bool> and not just a Bool (and not a @Binding), you can't treat it like you would if it were just a Bool. For example, hidden = false will not work with Binding<Bool>. Instead, to access the underlying Bool value, you can use its .wrappedValue property: hidden.wrappedValue = false.

    The two are are very similar, but different in a couple of important ways (like those detailed above). In practical terms:

    • If you're using a binding as a property on a View, you'll likely end up using @Binding.
    • If you're the binding it outside of a view (and thus don't have use of the DynamicProperty aspect), you'll likely use Binding<Bool> (technically, nothing is stopping you from using @Binding outside of a View, but it's a semantically odd decision).