First, you want an Observable class.
@Observable
class Player {
var name = "Anonymous"
var highScore = 0
}
In your top-level View, you want a @State var and you want to stick it in the subviews via enviornment()
, thus:
struct ContentView: View {
@State private var player = Player()
var body: some View {
VStack {
Text("Welcome!")
HighScoreView()
}
.environment(player)
}
}
Any sub-view (or sub-sub-view or sub-sub-sub-sub-view etc) can then read that var from the Enviroment, thus:
struct HighScoreView: View {
@Environment(Player.self) var player
var body: some View {
@Bindable var player = player
Stepper("High score: \(player.highScore)", value: $player.highScore)
}
}
Note the additional @Bindable
inside the view body. That arguably shouldn’t be necessary, but for iOS 17 at least, it is required if you want to read AND WRITE to the var, like our Stepper does.
The extra @Bindable var player = player
is NOT needed if you’re just reading from the var.
See Paul 5/12 for more.