SwiftUI has completely transformed the way we build user interfaces in the Apple ecosystem. Instead of constructing views imperatively, SwiftUI uses a declarative model, where the user interface is a direct function of the app’s state.
At the core of this system are two fundamental property wrappers:@State and @Binding.
Whether you are new to SwiftUI or already experienced with it, understanding these two concepts correctly is absolutely essential. Many of the most common SwiftUI bugs and unexpected behaviors come from misunderstanding how state flows between views.
In this tutorial you will learn:
- What state means in SwiftUI
- What
@Stateis - What
@Bindingis - How they relate to each other
- When to use each one
- Their similarities and differences
- Real examples in Xcode
1. The Concept of State in SwiftUI
Before talking about @State and @Binding, we need to understand what state means in SwiftUI.
State is any piece of data that affects what the user sees on screen.
Examples of state:
- Text the user types
- Whether a button is enabled
- Whether an alert is visible
- The value of a counter
- Whether a switch is on
In SwiftUI:
When the state changes, the view is automatically redrawn
This is what makes SwiftUI so powerful.
2. What is @State?
@State is a property wrapper that allows a view to store data that can change over time and belongs to that view.
SwiftUI watches that property, and when it changes, it re-renders the view.
Simple example:
struct ContentView: View {
@State private var counter = 0
var body: some View {
VStack {
Text("Counter: \(counter)")
Button("Increment") {
counter += 1
}
}
}
}Here:
counteris the view’s state- When it changes, SwiftUI redraws the
Text
Why do we use @State?
Because SwiftUI views are structs, and structs are immutable by default.@State lets SwiftUI store that value in external mutable memory.
3. Key Characteristics of @State
- Belongs to a view
- Is the source of truth
- Should only be modified by the view that owns it
- Is automatically observed by SwiftUI
Golden rule:
The view that creates the state owns it
4. What is @Binding?
@Binding does not store data.@Binding is a reference to a @State value that lives in another view.
It is a way of saying:
“I don’t own this value, but I can read and modify it.”
Example:
struct ParentView: View {
@State private var isOn = false
var body: some View {
ChildView(isOn: $isOn)
}
}
struct ChildView: View {
@Binding var isOn: Bool
var body: some View {
Toggle("Active", isOn: $isOn)
}
}Here:
isOnlives inParentViewas@StateChildViewreceives a@Binding- Both views work on the same value
5. The $ Symbol
When passing a @State to a @Binding, we use $.
Example:
$counterIt means:
“Pass a reference to the state, not the value.”
counter→ the value$counter→ the binding
6. Data Flow in SwiftUI
SwiftUI uses unidirectional data flow:
@State (Parent) → @Binding (Child)The parent:
- Creates and stores the state
The child:
- Uses it and can modify it
But the real owner remains the parent.
7. Similarities Between @State and @Binding
Both are related to state, and both trigger UI updates when their values change.
| Feature | @State | @Binding |
|---|---|---|
| Updates the UI when changed | Yes | Yes |
| Used in SwiftUI views | Yes | Yes |
| Connected to SwiftUI’s reactive system | Yes | Yes |
| Allows mutation | Yes | Yes |
8. Key Differences
This is the most important part.
| Concept | @State | @Binding |
|---|---|---|
| Stores the value | Yes | No |
| Source of truth | Yes | No |
| Can exist alone | Yes | No |
| Is initialized | Yes | No |
| References another value | No | Yes |
| Used to share state | No | Yes |
In one sentence:
@Statecreates state,@Bindingshares it.
9. Common Mistake: Using @State in a Child View
This is wrong:
struct ChildView: View {
@State var text: String
}This creates a copy, not a connection.
Correct version:
struct ChildView: View {
@Binding var text: String
}10. Real Example: A Form
struct FormView: View {
@State private var name = ""
var body: some View {
NameField(name: $name)
Text("Hello \(name)")
}
}
struct NameField: View {
@Binding var name: String
var body: some View {
TextField("Enter name", text: $name)
}
}Every time the user types:
- The
TextFieldchanges the@Binding - That updates the
@State - SwiftUI redraws both views
11. When to Use Each
Use @State when:
- The view owns the data
- The value is local
- It doesn’t need to be shared
Use @Binding when:
- The data comes from a parent view
- You need to modify it
- You must not create a copy
12. A Simple Rule
Ask yourself:
Does this value live here or come from somewhere else?
Lives here → @State
Comes from outside → @Binding
13. A Simple Analogy
Think of a light switch:
@Stateis the actual switch on the wall@Bindingis another button wired to the same switch
There is only one light, one source of truth.
14. Conclusion
@State and @Binding are two of the most important pillars of SwiftUI.
Understanding their relationship is key to building clean, reliable, and bug-free applications.
@Statecreates and owns data@Bindingshares it across views
Once you master this, SwiftUI stops feeling like magic — and starts feeling like elegant engineering.
If you have any questions about this article, please contact me and I will be happy to help you 🙂. You can contact me on my X profile or on my Instagram profile.