SwiftUI NavigationView 意外弹出到 Root

时间:2021-06-09 21:49:17

标签: swiftui swiftui-navigationlink swiftui-navigationview environmentobject

我已经创建了一些 SwiftUI 代码,它使用 EnvironmentObject 来存储布尔值以返回到根视图,另一个 EnvironmentObject 来存储旨在跨多个视图使用的分数变量.

在这个例子中,我有两个游戏,一个红色游戏和一个蓝色游戏。我有最初设置为 .redStacked 的布尔值(.blueStackedfalse)。它们各自的 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()
    }
}

0 个答案:

没有答案