66

This tutorial by Apple about SwiftUI uses a dollar sign to bind data, and I‘m having trouble finding more information about this data binding in SwiftUI.

Toggle(isOn: $showFavoritesOnly) {

You use the $ prefix to access a binding to a state variable, or one of its properties.

Is this some sort of inout type parameter? That uses the ampersand to pass it on.

mfaani
  • 33,269
  • 19
  • 164
  • 293
vrwim
  • 13,020
  • 13
  • 63
  • 118

2 Answers2

88

This is very well explained in WWDC 2019 video 415. You are merely looking at one special case of a broad language feature, namely property wrappers.

A property wrapper (such as @State) is actually a way of referring to an instance of a type (usually a struct or enum) with the same name (such as State). The latter provides instructions for turning this instance property into a computed property whose getter and setter are the getter and setter for a certain computed property of itself (its wrappedValue). It also typically holds private storage backing that computed property.

Thus, after the declaration

@State var showFavoritesOnly = true

...showFavoritesOnly is turned into a computed property, with its getter and setter supplied by the State struct. When you set showFavoritesOnly to true, that is routed through the State struct's setter and ends up in a stored property of the State instance.

All of this implies that somewhere there is a State instance associated with your showFavoritesOnly. And there is, but it's hidden from view. Its name, in case you'd like to see that State instance, is _showFavoritesOnly.

Okay, but when you say $showFavoritesOnly, you do not get a State struct; you get a Binding struct. Why? That's because a property wrapper has a mechanism for specifying what the returned value from the $ name should be. In the case of State, it specifies that this value should be its own binding property, which is a Binding (see the docs: https://developer.apple.com/documentation/swiftui/state).

By an amazing coincidence, Toggle's isOn initializer takes a Binding (again, see the docs, https://developer.apple.com/documentation/swiftui/toggle/3232112-init). You could not have set the Toggle's isOn to showFavoritesOnly even if you wanted to! Instead, you set it to the Binding<Bool> supplied by the State instance, so that the Toggle has automatic two-way communication with the State object. The SwiftUI framework enforces its own correct usage; a Toggle can exist only in relation to some binding that acts as the underlying source of truth for its on/off state. And because it's a binding, not a mere Bool, communication works in both directions: when the user taps the switch in the Toggle, the change in value flows "up" to the State variable by way of the binding.

matt
  • 515,959
  • 87
  • 875
  • 1,141
49

The $ is used in conjunction with property wrappers (previously known as "property delegates").

It's not an operator, but a prefix (thanks @matt!).

For more about property delegates, see this Swift Evolution document.

e.g. in @State var aState = false, State is a property wrapper.

This means that if we write:

  • aState we're accessing a Bool value
  • $aState we're accessing a Binding<Bool> value

Different property delegates will generate different values, called "projected values".

Nikolay Suvandzhiev
  • 8,465
  • 6
  • 41
  • 47
Matteo Pacini
  • 21,796
  • 7
  • 67
  • 74
  • 17
    You make it sound like some kind of operator. It isn't. The dollar sign is merely the first letter of the variable name. It doesn't "make" a binding. `$aState` _is_ the binding. – matt Jun 11 '19 at 20:45
  • The `Binding` value should be `projectedValue`, right? – Itachi Apr 28 '20 at 14:41
  • Also docs has a nice example in `Projecting a Value From a Property Wrapper` at https://docs.swift.org/swift-book/LanguageGuide/Properties.html – DanSkeel Nov 11 '20 at 19:49
  • @Itachi yes, `projectedValue` of @State property wrapper has type `Binding` – DanSkeel Nov 11 '20 at 19:51
  • 1
    I am now seeing `_aState` for `@State` and `@Binding` variables, what does it mean? As far as I can see, the underscore does the same as the dollar sign. – vrwim Apr 16 '21 at 14:25
  • @matt https://developer.apple.com/documentation/combine/published/projectedvalue "The projectedValue is the property accessed with the $ operator." What's the "operator"? – Paweł Brewczynski Mar 07 '23 at 09:49