DEV Community

Cover image for SwiftUI @State and @Binding
✨ thetealpickle πŸ“±
✨ thetealpickle πŸ“±

Posted on

SwiftUI @State and @Binding

The drop of SwiftUI this summer 2019 shook the iOS/Swift dev game. The way views are created and how data flows through apps have become declarative. BindableObject, Environment, State, Binding are new tools to cut through the waves and make it to the other side.


Property Wrappers

New in Swift 5.1, property wrappers. Property wrappers wrap property access with additional behavior. State and Binding are property wrappers.

Source of Truth

Source of truth is the biggest change with SwiftUI. Pre-SwiftUI, view controllers were in charge of their own data and if developers wanted a β€œsyncing” effect, they would need to create it themselves. begins reminiscing pre-swiftui data syncing bugs bugs bugs.

Apple said fuck that, use @State

State

With SwiftUI, the emphasis is on your app having one source of truth, which is defined using @State. State lives in this magically bubble outside of your view. Views are volatile. State is persistent storage created by SwiftUI on your view’s behalf.

@State var isPickle: Bool = true
Enter fullscreen mode Exit fullscreen mode

The @State property wrapper tells system, the property is a value that changes over time and the views depends on the value. Any runtime changes to a State wrapped property are recognized and triggers a re-rendering of only the portions of the views which utilize the property’s value #efficient. Since changes flow down to all of the view's children, State wrapped properties should be owned by one view which is the top-most view of the application.

Speaking of children, how the heck does State get passed through to other views if State should be defined in only one view??? Binding πŸ˜‰

Binding

The @Binding property wrapper tells the system the property has read/write access to the value without ownership. Binding properties have their values passed in from a parent view as a binding, for this reason, providing a default value is not needed.

Creating a binding occurs by passing in a State property with the $ prefix and provides the child view with a reference to the State property.

@State var isPickle: Bool = true

var body : some View {
   ChildView(showPickleEmoji: $isPickle )
}
Enter fullscreen mode Exit fullscreen mode

In the ChildView

@Binding showPickleEmoji: Bool
Enter fullscreen mode Exit fullscreen mode

Binding wrapped properties are provided a reference to the app’s State so any changes to values on Binding wrapped properties trigger changes across the application to whatever view portions are dependent on that State’s value.

Ownership

The biggest difference between State and Binding is ownership. Views with property's marked with State have ownership. The system created storage on that specific views behalf. With property's marked with Binding, the view has read and write access, but not ownership.

Like living with someone and having a pet. The pet is in both individuals lives. Both individuals take care of the pet, give the pet affection, take the pet out. They both have access. BUT, on the day one decides to move, the pet ultimately stays with the owner.

@thetealpickle on the internet. Namaste.

This article was brought to you by JESSICA JEAN JOSEPH Β© THETEALPICKLE

Top comments (4)

Collapse
 
ricardo1980 profile image
Ricardo Ruiz Lopez

Thanks for your explanation.

What is the relationship (if there is any) between @State/@Binding and @ObservedObject/@Publised?

Thanks.

Collapse
 
thetealpickle profile image
✨ thetealpickle πŸ“± • Edited

YES!

So with SwiftUI the State and Binding are ways for the views to have access to a consistent source of truth. State creates an instance of truth, whereas Binding passes a reference. Binding is useful when you want to pass a select subsection of data that can be mutated by child views. Binding assures the mutated data remains synced with your source of truth (often State, but can also be an EnvironmentObject or @ObservedObject)

ObservableObject (protocol) and @Published are ways to conform your custom classes to the declarative paradigm. The class itself, when conformed to ObservableObject can then be passes in as an EnvironmentObject and shared everywhere. An ObservableObject can also be used with @ObservedObject to invalidate views when there are any changes. Published is used to mark specific class properties which can be mutated by your views. Published properties can be used wherever a State or Binding is asked.

When referring to view invalidation, what are we talking about?
Any changes that would trigger the compiler to generate a new view.
Properties that would change a view's data essentially, invalidates the view.
AND, luckily for us, views are structs so they're cheaper to replace than a class counterpart (by value vs. by reference)

Hope this helped !! 😊

Collapse
 
taylorpaul profile image
Taylor Paul

Great explanation that was easy to understand, and entertaining to read. Your pet analogy will help me retain this information. Thank you for your article!

Collapse
 
nochphanith profile image
Phanith

can you help me how to share data binding between view and class example when I get data from API success I would like to show Alert but Alert there need isPresented type is Binding