My program is producing the error: Thread 1: Fatal error: No ObservableObject of type Variables found. A View.environmentObject(_:) for Variables may be missing as an ancestor of this view.
, and I don't really understand what this error means.
Here's a minimal reproducible exmaple of my code that's producing the error:
import SwiftUI
struct ContentView: View {
@StateObject var storage = Variables()
var body: some View {
AddToScore()
VStack {
Button("remove points") {
storage.score -= 1
}
Text("text text etxt dfahjadfbadful")
}.environmentObject(storage)
}
}
struct AddToScore: View {
@EnvironmentObject var storage: Variables
var body: some View {
VStack {
Text("Point generator")
.font(.title)
HStack {
Button("Get points!") {
storage.score += 1
}
Text("\(storage.score)")
}
}
}
}
class Variables: ObservableObject {
@Published var score = 0
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
In your code .environmentObject(storage)
is not in range of AddToScore(). They are both 'on the same level', or siblings to eachother. .environmentObject(storage)
needs to be on the level above, or an ancestor, as mentioned in the error:
A View.environmentObject(_:) for Variables may be missing as an ancestor of this view.
Like this:
import SwiftUI
struct ContentView: View {
@StateObject var storage = Variables()
var body: some View {
VStack {
// AddToScore() needs to be a child of a closure containing
// .environmentObject(storage).
AddToScore()
Button("remove points") {
storage.score -= 1
}
Text("text text etxt dfahjadfbadful")
}.environmentObject(storage)
}
}
struct AddToScore: View {
@EnvironmentObject var storage: Variables
var body: some View {
VStack {
Text("Point generator")
.font(.title)
HStack {
Button("Get points!") {
storage.score += 1
}
Text("\(storage.score)")
}
}
}
}
class Variables: ObservableObject {
@Published var score = 0
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
You could also add .environmentObject(storage)
directly on AddToScore()
(as shown on the comment by Umer Khan), but note that other views/objects on the same level won't be able to access the EnvironmentObject. Only things inside AddToScore()
.
AddToScore().environmentObject(storage)