Welcome to the “Passing @State to Subviews” demo. In this demo, you’ll learn how to share state between views in SwiftUI. You’ll use the simple counter app to demonstrate this concept. Time to get started!
First, open the starter Counter Xcode project in the 07-Passing-@State-to-Subviews-Demo/Starter directory. This project contains all the starter code you’ll need for this demo.
CounterApp.swift
file, you’ll find the CounterView
struct. This view displays the current count and includes buttons to increment and decrement the count:
struct CounterView: View {
@State private var count: Int = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
Button("Decrement") {
count -= 1
}
}
}
}
ContentView
struct. It currently looks like this:
struct ContentView: View {
var body: some View {
VStack {
CounterView()
}
}
}
ContentView
simply displays CounterView
. Run the app to see the counter in action. Tap the Increment and Decrement buttons to change the count.
CounterView
to receive the count as a parameter instead of managing its own state. This change will demonstrate how to pass state from a parent view to a subview.
CounterView
, there’s a line defining a @State
property for the count. Replace this line with a constant property, as CounterView
will now receive the count value as a parameter from its parent view:
struct CounterView: View {
let count: Int
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
Button("Decrement") {
count -= 1
}
}
}
}
count
property when creating an instance of CounterView
, add an initializer to the struct. This initializer takes the count value as a parameter and assigns it to the count
property:
struct CounterView: View {
let count: Int
init(count: Int) {
self.count = count
}
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
Button("Decrement") {
count -= 1
}
}
}
}
CounterView
, remove the Button
views. You should have a Text
view that displays the count:
struct CounterView: View {
let count: Int
init(count: Int) {
self.count = count
}
var body: some View {
VStack {
Text("Count: \(count)")
}
}
}
CounterView
to receive the count as a parameter from its parent view and display it in a Text
view.
CounterView
no longer has a @State
property. It now has a constant property count
that it uses to display the count value. CounterView
is stateless.
ContentView
to manage the state and pass it to CounterView
. Then, add a count
@State
property:
struct ContentView: View {
@State private var count: Int = 0
var body: some View {
VStack {
CounterView()
}
}
}
CounterView
:
struct ContentView: View {
@State private var count: Int = 0
var body: some View {
VStack {
CounterView(count: count)
}
}
}
ContentView
:
struct ContentView: View {
@State private var count: Int = 0
var body: some View {
VStack {
CounterView(count: count)
Button("Increment") {
count += 1
}
Button("Decrement") {
count -= 1
}
}
}
}
ContentView
has a @State
property count
that it passes to its child CounterView
. ContentView
also includes the buttons to increment and decrement the count. When you tap the buttons, ContentView
updates its state, and CounterView
automatically reflects the changes.
ContentView
and passed to CounterView
.
@State
in SwiftUI.