使用警报按钮导航回主菜单在 SwiftUI 中查看

Navigating back to main menu View in SwiftUI with Alert Button

我有一个包含两个已定义视图的应用程序。我使用 NavigationView 在它们之间移动。我想要警报按钮将用户切换回主菜单视图,我什至找到了答案,但在我使用它之后,它产生了这样的屏幕:

如何让我的应用程序以更好的方式从辅助视图导航回主视图?

第二个视图的代码(第一个只是指向第二个的 NavigationLink):

import SwiftUI

struct GameView: View {
    
    
    @State private var questionCounter = 1
    
    @State var userAnswer = ""
    
    @State private var alertTitle = ""
    
    @State private var gameOver = false
    @State private var menuNavigation = false
    
    
    var body: some View {
        NavigationView{
            ZStack{
                NavigationLink(destination:ContentView(), isActive: $menuNavigation){
                    Text("")
                }
            VStack{
                
                Text("Give the answer")
                TextField("Give it", text: $userAnswer)
                
                Button("Submit", action: answerQuestion)
            }
            .alert(isPresented: $gameOver) {
                Alert(title: Text(alertTitle),
                      dismissButton: Alert.Button.default(
                        Text("Back to menu"), action: {
                            menuNavigation.toggle()
                        }
                      )
                )
                }
            }
            }
            
            }
    
    func answerQuestion() {
        
        questionCounter += 1
        
        if questionCounter == 2 {
            gameOver.toggle()
            alertTitle = "Game Over"
        
        }
        
    }
}

感谢您的帮助:)

要实现您的期望,您实际上需要在 ContentView 中添加 NavigationView,如果这是您的主视图。因为你从 ContentView 导航到 GameView,而你在这里问的是如何导航回来。

应用上述概念,您可以关闭 GameView 返回视图。

这是实现该目的的示例代码:

主视图示例:

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink {
                GameView()
                
                    // This is how you hide the "<Back" button, so the user
                    // can navigate back only when tapping the alert
                    .navigationBarHidden(true)
            } label: {
                Text("Go to game view")
            }
        }
    }
}

游戏视图示例:

struct GameView: View {
    
    // This variable will dismiss the view
    @Environment(\.presentationMode) var presentationMode
    
    @State private var questionCounter = 1
    @State var userAnswer = ""
    @State private var alertTitle = ""
    @State private var gameOver = false
    
    // No need to use this variable
    // @State private var menuNavigation = false
    
    var body: some View {
        
        // No need to have a NavigationView
        // NavigationView {
        
            // ZStack has no function apparently...
            // ZStack{
        
                // No need to have a NavigationLink
                // NavigationLink(destination:ContentView(), isActive: $menuNavigation){
                //    Text("")
                //}
            VStack {
                
                Text("Give the answer")
                TextField("Give it", text: $userAnswer)
                
                Button("Submit", action: answerQuestion)
            }
            .alert(isPresented: $gameOver) {
                Alert(title: Text(alertTitle),
                      dismissButton: Alert.Button.default(
                        Text("Back to menu"), action: {
                            
                            // This is how you go back to ContentView
                            presentationMode.wrappedValue.dismiss()
                        }
                      )
                )
        }
    }
    
    
    func answerQuestion() {
        
        questionCounter += 1
        
        if questionCounter == 2 {
            gameOver.toggle()
            alertTitle = "Game Over"
        }
    }
}

我找到了一种使建议的方法更简单的方法(无需使用整个 presentationMode 语法):

struct GameView: View {
   
    @Environment(\.dismiss) var dismiss
    
    @State private var questionCounter = 1
    @State var userAnswer = ""
    @State private var alertTitle = ""
    @State private var gameOver = false
   
    
    var body: some View {
    
            VStack {
                
                Text("Give the answer")
                TextField("Give it", text: $userAnswer)
                
                Button("Submit", action: answerQuestion)
            }
            .alert(isPresented: $gameOver) {
                Alert(title: Text(alertTitle),
                      dismissButton: Alert.Button.default(
                        Text("Back to menu"), action: {
                            
                            dismiss()
                        }
                      )
                )
        }
    }
    
    
    func answerQuestion() {
        
        questionCounter += 1
        
        if questionCounter == 2 {
            gameOver.toggle()
            alertTitle = "Game Over"
        }
    }
}