Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

Understanding State & Binding in SwiftUI
Written by Team Kodeco

State and binding are two fundamental concepts in SwiftUI that enable you to create dynamic and interactive interfaces. Understanding them is key to managing user interface state effectively.

Understanding State

In SwiftUI, State is a property wrapper that you use to store simple values that belong to a specific view and that change over time. When a State value changes, the view invalidates its appearance and recomputes the body property. This means that SwiftUI automatically re-renders the view whenever the State changes.

For instance, consider the following example that manages the state of a Toggle view:

struct ContentView: View {
  @State private var isSwitchedOn = false

  var body: some View {
    VStack {
      Toggle(isOn: $isSwitchedOn) {
        Text("Turn me on or off")
      }
      if isSwitchedOn {
        Text("The switch is on!")
      }
    }
    .padding()
  }
}

Your preview should look like this:

Use the State property wrapper to manage data local to a single view.
Use the State property wrapper to manage data local to a single view.

In the above example, isSwitchedOn is a State property that keeps track of whether a toggle switch is on or off. When the toggle is flipped, isSwitchedOn changes, causing the view to re-render and update the displayed text.

Understanding Binding

Binding in SwiftUI creates a two-way connection between a property that stores data and a view that displays and changes that data. It allows the data to be mutable so that SwiftUI can modify the value inside a structure that would usually be immutable.

Consider the following example:

struct ContentView: View {
  @State private var selectedColor = Color.red

  var body: some View {
    VStack {
      Rectangle()
        .fill(selectedColor)
        .frame(width: 100, height: 100, alignment: .center)

      ColorPickerView(selectedColor: $selectedColor)
    }
    .padding()
  }
}

struct ColorPickerView: View {
  @Binding var selectedColor: Color

  let colors: [Color] = [.red, .green, .blue, .yellow, .orange]

  var body: some View {
    HStack {
      ForEach(colors, id: \.self) { color in
        Rectangle()
          .fill(color)
          .frame(width: 50, height: 50)
          .onTapGesture {
            selectedColor = color
          }
      }
    }
  }
}

Your preview should look like this:

Bindings enable seamless interactions between views.
Bindings enable seamless interactions between views.

In this example, you have a ContentView that contains a rectangle whose fill color is determined by the selectedColor state. You also have a ColorPickerView that accepts a binding to the selectedColor. When a color in the ColorPickerView is tapped, it updates the selectedColor which then changes the fill color of the rectangle in the ContentView. This is possible because of the two-way connection created by the binding — the ColorPickerView not only reads the selectedColor value but also has the ability to change it.

In conclusion, state and binding are crucial tools in SwiftUI for managing the state of your views and creating interactive user interfaces. By understanding and utilizing these concepts, you can create dynamic and responsive UIs that automatically update in response to user interaction.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.