SwiftUI登录成功后点击Alert的OK无法跳转至目标视图求助
问题原因及解决方案
问题核心是**navigationDestination的位置错误**:你将导航目标放在了NavigationStack外部,而SwiftUI要求导航目标必须嵌套在NavigationStack内部才能触发页面跳转。
修复步骤
- 将
.navigationDestination(isPresented: $LoginIn) { MainMenu() }移动到NavigationStack的闭包内部,放在VStack同级位置。 - (可选规范优化)变量名
LoginIn不符合Swift小写开头的命名习惯,建议改为loginIn,枚举值.Login同步改为.login。
修正后的完整代码
import SwiftUI import SwiftData struct LoginView: View { @Environment(\.modelContext) private var context @Query private var userInfo: [User] @State private var stuid = "" @State private var password = "" @State private var loginIn = false // 修正命名规范 enum myAlert { case login case error case noinput } @State private var alertType: myAlert? = nil @State private var showAlert = false var body: some View { NavigationStack { VStack { Spacer() HStack { Spacer() Spacer() Spacer() Spacer() Image(systemName: "road.lanes.curved.right") .font(.title) Text("登录") .font(.largeTitle) .bold() Spacer() Spacer() Spacer() Spacer() Spacer() } .padding() TextField("学号", text: $stuid) .padding() .frame(width: 300, height: 50) .background(Color.black.opacity(0.05)) .border(.black, width: 2) .cornerRadius(10) SecureField("密码", text: $password) .padding() .frame(width: 300, height: 50) .background(Color.black.opacity(0.05)) .border(.black, width: 2) .cornerRadius(10) Button("Login") { showAlert.toggle() authenticateUser(stuid: stuid, password: password) } .alert(isPresented: $showAlert, content: { getAlert() }) .foregroundColor(.white) .frame(width: 300, height: 50) .background(Color.black) .cornerRadius(10) .padding() Spacer() } // 导航目标移至NavigationStack内部 .navigationDestination(isPresented: $loginIn) { MainMenu() } } .navigationBarBackButtonHidden() } func authenticateUser(stuid: String, password: String) { if stuid.isEmpty || password.isEmpty { alertType = .noinput return // 提前终止,避免无效循环 } let isAuthenticated = userInfo.contains { $0.stuId == stuid && $0.password == password } alertType = isAuthenticated ? .login : .error } func getAlert() -> Alert { switch alertType { case .login: return Alert( title: Text("登录成功"), primaryButton: .default(Text("OK"), action: { loginIn = true print(loginIn) }), secondaryButton: .cancel()) case .noinput: return Alert(title: Text("请输入您的学号和密码")) case .error: return Alert(title: Text("学号或密码错误")) default: return Alert(title: Text("ERROR")) } } }
额外优化说明
- 在
authenticateUser中添加提前返回逻辑,避免空输入时执行后续循环,提升效率。 - 使用
userInfo.contains替代手动遍历,代码更简洁高效。
内容的提问来源于stack exchange,提问作者zzhzzh
相关产品推荐
相关产品推荐

