You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI登录成功后点击Alert的OK无法跳转至目标视图求助

问题原因及解决方案

问题核心是**navigationDestination的位置错误**:你将导航目标放在了NavigationStack外部,而SwiftUI要求导航目标必须嵌套在NavigationStack内部才能触发页面跳转。

修复步骤

  1. 将.navigationDestination(isPresented: $LoginIn) { MainMenu() }移动到NavigationStack的闭包内部,放在VStack同级位置。
  2. (可选规范优化)变量名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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:51:25