使用警报按钮导航回主菜单在 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"
}
}
}
我有一个包含两个已定义视图的应用程序。我使用 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"
}
}
}