Swift and SwiftUI tutorials for Swift Developers

SwiftUI @State vs @Binding with Example and Explanation

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 @State is
  • What @Binding is
  • 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:

  • counter is 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:

  • isOn lives in ParentView as @State
  • ChildView receives a @Binding
  • Both views work on the same value

5. The $ Symbol

When passing a @State to a @Binding, we use $.

Example:

$counter

It 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 changedYesYes
Used in SwiftUI viewsYesYes
Connected to SwiftUI’s reactive systemYesYes
Allows mutationYesYes

8. Key Differences

This is the most important part.

Concept@State@Binding
Stores the valueYesNo
Source of truthYesNo
Can exist aloneYesNo
Is initializedYesNo
References another valueNoYes
Used to share stateNoYes

In one sentence:

@State creates state, @Binding shares 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 TextField changes 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:

  • @State is the actual switch on the wall
  • @Binding is 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.

  • @State creates and owns data
  • @Binding shares 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

How to Show an Alert in SwiftUI

Next Article

Extensions in Swift - Tutorial with Examples

Related Posts