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>
CodePudding user response:
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 aView
, but it's a semantically odd decision).