SwiftUI Blog

Mastering SwiftUI: Your Guide to Building Beautiful, Intuitive Apps.

State And Binding

Two fundamental concepts in SwiftUI are State and Binding. Following the official documentation, we can say:
• State is a property wrapper type that can read and write a value managed by SwiftUI.
• Binding is a property wrapper type that can read and write a value owned by another view.

Let’s explain with an example. Imagine that we want to get text input from the user and simply re-display what they type.

struct ContentView: View {
    @State var text = ""

    var body: some View {
        VStack {
            TextField("Placeholder", text: $text)
            Text("Typed: \(text)")
        }.padding()
    }
}

Thus, we define a String variable as a State, because this variable can be read and changed within SwiftUI. But how does the change happen? Through the TextField. The TextField is defined by setting a placeholder and linking it to a variable that will hold the text input by the user. The TextField binds to the text variable to allow changes, so it’s passed using the $ prefix. Simply put, you can think of this as similar to passing by reference; instead of using &, we use $.

Let’s create a component to help us understand Binding. We want to create a button that works as an incrementer: every time it’s clicked, the passed value increases by one.

struct ContentView: View {
    @State var number: Int = 0
    var body: some View {
        VStack {
            IncrButton(number: $number)
            Text("Incremented: \(number)")
        }.padding()
    }
}

struct IncrButton: View {
    @Binding var number: Int
    var body: some View {
        VStack {
            Button(action: { self.number += 1 }) {
                Text("Increment")
            }
        }.padding()
    }
}

In this case, we define in the ContentView a number variable as State and pass it to the IncrButton.

In IncrButton, we see that number is a variable with a Binding property, so it can modify the value of this variable, which is bound to a variable from another view.

Now try to creat your binding component.