SwiftUI登录成功后跳转至新视图的实现问题求助
解决方案
方法一:适配iOS 15及更早版本(用NavigationLink绑定状态)
- 在
ContentView里新增一个控制登录状态的@State变量:
@State private var isLoggedIn = false
- 修改登录按钮的触发逻辑,验证成功后设置
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() }
- 在
NavigationView内部添加一个隐藏的NavigationLink,通过状态绑定触发跳转:
NavigationView{ ZStack{ // 原有VStack内容保持不变 } .offset(y: editingMode ? -150 : 0) .navigationBarHidden(true) // 隐藏的跳转触发器 NavigationLink(destination: HomeView(), isActive: $isLoggedIn) { EmptyView() } }
方法二:适配iOS 16及以上版本(用navigationDestination)
苹果在iOS16推出了更简洁的导航API,推荐优先使用:
- 同样新增
@State private var isLoggedIn = false变量。 - 登录按钮的触发逻辑和方法一一致。
- 替换
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
相关产品推荐
相关产品推荐

