我创建了一些 SwiftUI 代码,这些代码使用一个EnvironmentObject
来存储布尔值以返回到根视图,另一个EnvironmentObject
用于存储一个旨在跨多个视图使用的分数变量。
在这个例子中,我有两个游戏,一个红色游戏和一个蓝色游戏。我有.redStacked
最初.blueStacked
设置为false
. 他们各自NavigationLinks
将它们设置为true
. 在游戏结束时,“主页”按钮将其设置回false
,这会将导航堆栈展开回根视图。
我遇到的问题是对分数 EnvironmentObject
的任何更新都会意外地过早地将导航堆栈弹出回根视图。
在下面的示例代码中,游戏之间的唯一区别是红色游戏按钮将 +1 添加到其 score 环境变量。在这种情况下,添加了一个点并执行到最终页面的导航链接,但随后它立即橡皮筋回到开头。Blue Game 没有按预期更新 score 环境变量和转换。
我欢迎任何关于为什么会发生这种情况的见解。提前致谢。
import SwiftUI
class Pop: ObservableObject {
@Published var redStack = false
@Published var blueStack = false
}
class Score: ObservableObject {
@Published var redTotal = 0
@Published var blueTotal = 0
}
struct GameSelection: View {
@ObservedObject var pop = Pop()
@ObservedObject var score = Score()
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: RedStart(), isActive: $pop.redStack) {
Text("Play Red Game") //Tapping this link sets redStacked to true
}.foregroundColor(.red)
Divider()
NavigationLink(destination: BlueStart(), isActive: $pop.blueStack) {
Text("Play Blue Game") //Tapping this link sets blueSteacked to true
}.foregroundColor(.blue)
}
}
.environmentObject(score)
.environmentObject(pop)
}
}
struct RedStart: View {
@State var goToNextView : Bool = false
@EnvironmentObject var score : Score
var body: some View {
VStack {
NavigationLink(destination: RedEnd(), isActive: $goToNextView) {}
Button(action: {
score.redTotal += 1
goToNextView = true
}, label: {
Text("Add 1 Point. Move to Next Screen")
.foregroundColor(.red)
})
}
}
}
struct BlueStart: View {
@State var goToNextView : Bool = false
@EnvironmentObject var score : Score
var body: some View {
VStack {
NavigationLink(destination: BlueEnd(), isActive: $goToNextView) {}
Button(action: {
// score.blueTotal += 1
goToNextView = true
}, label: {
Text("Do NOT add points. Move to Next Screen")
.foregroundColor(.blue)
})
}
}
}
struct RedEnd: View {
@EnvironmentObject var pop: Pop
@EnvironmentObject var score: Score
var body: some View {
Button(action: {
pop.redStack = false
}, label: {
VStack {
Text("Your Score: \(score.redTotal)")
Text("Game Over")
Image(systemName: "house.fill")
}
.foregroundColor(.red)
})
}
}
struct BlueEnd: View {
@EnvironmentObject var pop: Pop
@EnvironmentObject var score: Score
var body: some View {
Button(action: {
pop.blueStack = false
}, label: {
VStack {
Text("Your Score: \(score.blueTotal)")
Text("Game Over")
Image(systemName: "house.fill")
}.foregroundColor(.blue)
})
}
}
struct GameSelection_Previews: PreviewProvider {
static var previews: some View {
GameSelection()
}
}