I have an app with two defined views. I use NavigationView to move between them. I wanted the alert button to switch users back to Main Menu View and I have even found an answer, but after I used it, it produced the screen like this:
How can I let my app navigate back to the main view from the secondary view in a better way?
The code for the second view (first is just a NavigationLink pointing to the second):
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"
}
}
}
Thanks for your help :)
To achieve what you are expecting, you actually need to add the NavigationView
inside ContentView
, if that's your main view. Because you navigate from ContentView
to GameView
, and what you are asking here is how to navigate back.
Applying the concept above, you can just dismiss GameView
to go back to the in view.
Here is a sample code to achieve that:
Example of main view:
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")
}
}
}
}
Example of 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"
}
}
}