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

SwiftUI登录成功后跳转至新视图的实现问题求助

解决方案

方法一:适配iOS 15及更早版本(用NavigationLink绑定状态)

  1. 在ContentView里新增一个控制登录状态的@State变量:
@State private var isLoggedIn = false
  1. 修改登录按钮的触发逻辑,验证成功后设置isLoggedIn为true:
Button(action: {
    if self.username == storedUsername && self.password == storedPassword {
        self.authenticationDidSucceed = true
        self.authenticationDidFail = false
        // 可选:延迟1秒跳转,让用户看到成功提示
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.isLoggedIn = true
            self.authenticationDidSucceed = false
        }
    } else {
        self.authenticationDidFail = true
    }
}) {
    LoginButtonContent()
}
  1. 在NavigationView内部添加一个隐藏的NavigationLink,通过状态绑定触发跳转:
NavigationView{
    ZStack{
        // 原有VStack内容保持不变
    }
    .offset(y: editingMode ? -150 : 0)
    .navigationBarHidden(true)
    // 隐藏的跳转触发器
    NavigationLink(destination: HomeView(), isActive: $isLoggedIn) {
        EmptyView()
    }
}

方法二:适配iOS 16及以上版本(用navigationDestination)

苹果在iOS16推出了更简洁的导航API,推荐优先使用:

  1. 同样新增@State private var isLoggedIn = false变量。
  2. 登录按钮的触发逻辑和方法一一致。
  3. 替换NavigationView为NavigationStack,并添加navigationDestination:
NavigationStack{
    ZStack{
        // 原有VStack内容保持不变
    }
    .offset(y: editingMode ? -150 : 0)
    .navigationBarHidden(true)
    .navigationDestination(isPresented: $isLoggedIn) {
        HomeView()
    }
}

完整修改后的ContentView代码(以方法一为例)

import SwiftUI

let lightGreyColor = Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0)
let storedUsername = "Myusername"
let storedPassword = "Mypassword"

struct ContentView: View {

    @State var username: String = ""
    @State var password: String = ""
    @State var authenticationDidFail: Bool = false
    @State var authenticationDidSucceed: Bool = false
    @State var editingMode: Bool = false
    @State private var isLoggedIn = false

    var body: some View {
        NavigationView{
            ZStack{
                VStack {
                    WelcomeText()
                    UserImage()
                    UsernameTextField(username: $username)
                    PasswordSecureField(password: $password)
                    if authenticationDidFail {
                        Text("Information not correct. Try again.")
                            .offset(y: -10)
                            .foregroundColor(.red)
                    }
                    Button(action: {
                        if self.username == storedUsername && self.password == storedPassword {
                            self.authenticationDidSucceed = true
                            self.authenticationDidFail = false
                            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                                self.isLoggedIn = true
                                self.authenticationDidSucceed = false
                            }
                        } else {
                            self.authenticationDidFail = true
                        }
                    }) {
                        LoginButtonContent()
                    }
                }
                .padding()
                if authenticationDidSucceed {
                    Text("Login Succeeded!")
                        .font(.headline)
                        .frame(width: 250, height: 80)
                        .background(Color.green)
                        .cornerRadius(20.0)
                        .foregroundColor(.white)
                        .transition(.opacity)
                        .animation(.easeInOut, value: authenticationDidSucceed)
                }
            }
            .offset(y: editingMode ? -150 : 0)
            .navigationBarHidden(true)
            NavigationLink(destination: HomeView(), isActive: $isLoggedIn) {
                EmptyView()
            }
        }
    }
}

// 以下子视图代码保持不变
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct WelcomeText: View {
    var body: some View {
        VStack {
            Text("Welcome")
                .font(.largeTitle)
                .fontWeight(.semibold)
                .padding(.bottom, 20)
        }
    }
}

struct UserImage : View {
    var body: some View {
        return Image("userImage")
            .resizable()
            .aspectRatio(UIImage(named:"userImage")!.size, contentMode: .fill)
            .frame(width: 150, height: 150)
            .clipped()
            .cornerRadius(150)
            .padding(.bottom, 75)
    }
}

struct LoginButtonContent : View {
    var body: some View {
        return Text("LOGIN")
            .font(.headline)
            .foregroundColor(.white)
            .padding()
            .frame(width: 220, height: 60)
            .background(Color.green)
            .cornerRadius(15.0)
    }
}

struct UsernameTextField : View {
    @Binding var username: String
    var body: some View {
        return TextField("Username", text: $username)
            .padding()
            .background(lightGreyColor)
            .cornerRadius(5.0)
            .padding(.bottom, 20)
    }
}

struct PasswordSecureField : View {
    @Binding var password: String
    var body: some View {
        return SecureField("Password", text: $password)
            .padding()
            .background(lightGreyColor)
            .cornerRadius(5.0)
            .padding(.bottom, 20)
    }
}

关键说明

  • 隐藏的NavigationLink不会在界面上显示,仅通过状态变化触发跳转。
  • 延迟跳转是为了让用户看到登录成功提示,可根据需求调整时长或直接移除。
  • iOS16+优先用NavigationStack,它是苹果官方推荐的新导航组件,逻辑更清晰。

内容的提问来源于stack exchange,提问作者KrazyCrave

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:20:44