SwiftUI: “@State” and “@Binding”

Stefano Frosoni
If let swift = Programming!
3 min readDec 10, 2019

--

One of the biggest announcements from WWDC19 was SwiftUI. SwiftUI is a user interface framework that lets us design apps in a declarative and highly composable way. We re going to implement a swift UI example that makes use of “@State” and “@Binding” that are Property Wrappers newly introduced in Swift 5.1.

“@State”

SwiftUI use “@State” to allow you to modify values inside a struct, which would normally not be allowed because structs are value types.

While Views are volatile. State is a persistent storage created by SwiftUI on your view’s behalf. SwiftUI can destroy and recreate your view whenever needed without losing the state that the property was storing. When the state value changes, the view invalidates its appearance and recomputes the body.

Use the state as the single source of truth for a given view.

Remember that “@State” shouldn’t be shared with other views and that’s why Apple recommends you mark those properties as private

“@Binding”

SwiftUI use “@Binding” to tells the system that a property has read/write access to a value without ownership. Creating a binding occurs by passing in a State property with the “$” prefix. We use $ to pass a binding reference, because without $ Swift will pass a copy of the value instead of passing bindable reference.

The biggest difference between State and Binding is ownership. Views with property’s marked with State have ownership.

Let’s see the example to understand better a real use.

Here below we have a child view (MySlider) that containts an horizontal stackview with a slider and two texts showing the range of the slider. The slider use the minValue and the maxValue properties for its range.

The binding wrapped property “value” is passed to the Slider’s value so that this property is updated when the slider changes its value; in this way MySlider keep a reference of the slider’s value.

On the parent view (ContentView) we have a State property sliderValue to keep memory of the value of the slider outside of the child view. When the Slider is created we create a binding by passing in the sliderValue property with the $ prefix and so creating a reference to the State property.

The initial value of 50 is passed to the slider as default value. The sliderValue is then printed in a Text view

The MySlider View doesn’t just read the value of “sliderValue”, it also writes its value. MySlider can read and write the value of ContentView’s sliderValue property, but it can’t observe the changes using this binding.

As soon as MySlider changes value of the sliderValue property, SwiftUI will recreate ContentView and then MySlider as its child.

This is what’s called a two-way binding, because any changes to the value of “sliderValue” will update the slider in the child View, and any changes to the slider will update “sliderValue” in the parent View. This new, two way communication drastically simplifies our code and reduces the need for the View Controllers in SwiftUI.

To better understand how the Data Flow through SwiftUI works I suggest to watch this video from the WWDC19

Here you can find the full code of this demo.

Thanks for your reading.

Get in touch on Twitter: stefanofrosoni

--

--