我已经创建了一些 SwiftUI 代码,它使用 EnvironmentObject
来存储布尔值以返回到根视图,另一个 EnvironmentObject
来存储旨在跨多个视图使用的分数变量.
在这个例子中,我有两个游戏,一个红色游戏和一个蓝色游戏。我有最初设置为 .redStacked
的布尔值(.blueStacked
和 false
)。它们各自的 NavigationLinks
将它们设置为 true
。在游戏结束时,“主页”按钮将其设置回 false
,这会将导航堆栈展开回到根视图。
我遇到的问题是,对 score EnvironmentObject
的任何更新都会意外且过早地将导航堆栈弹出回根视图。
在下面的示例代码中,游戏之间的唯一区别是红色游戏按钮为其 score 环境变量增加了 +1。在这种情况下,添加一个点并执行指向最终页面的导航链接,但随后它立即返回到开头。 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()
}
}