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.