@State and @BindingThese are the lesson notes for this day. Its build-along tutorial and flash cards have not been written yet.
@State and @Binding@State stores a value that belongs to one view. SwiftUI keeps that storage alive for as long as the view is on screen, even though the view struct itself is re-created over and over. When the value changes, the view's body runs again. Mark @State properties private: only the view that owns the value should set it. @Binding is a reference to state that is owned somewhere else. It lets a child view read and write a value without owning it. You make a binding from state by writing $ in front of the name.
The rule to hold on to: each piece of state has one owner — the single source of truth. Every other view receives either a plain value, if it only reads, or a Binding, if it must write.
As of Xcode 27, @State initializes lazily: an object stored in it is created exactly once for the lifetime of the view (this also applies when running on iOS 17 and later). One result is that giving a @State property a default value and also assigning it in init is now a compile error. Use one or the other.
struct CounterScreen: View {
@State private var count = 0 // this view owns the value
var body: some View {
VStack {
Text("Count: \(count)") // reads it
StepButtons(count: $count) // lends it to a child, read-write
}
}
}
struct StepButtons: View {
@Binding var count: Int // does not own it; edits the owner's value
var body: some View {
HStack {
Button("-") { count -= 1 }
Button("+") { count += 1 }
}
}
}
Exercise
Build a counter. Move the + and − buttons into a separate child view that receives a Binding. Then add a second child view that only displays the count and receives a plain Int.
@State value, and how long does it live?count and passing $count to a child view?@State properties be private?