iOS16+ Google登录后无法跳转至全屏UserProfileView问题求助
问题原因
你的代码存在两个核心问题导致UserProfileView内嵌在ContentView中:
- NavigationStack嵌套错误:你在
signedIn分支内创建了新的NavigationStack,这个栈是ContentView的VStack/HStack子视图,仅占用局部空间,因此跳转后的UserProfileView会被限制在该区域内。 - 缺少导航目标配置:未为NavigationStack设置
navigationDestination,明确指定路径添加特定值时应显示的视图。
调整ContentView结构,将NavigationStack作为顶级视图,通过监听认证状态变化触发导航:
import SwiftUI import GoogleSignIn import GoogleSignInSwift struct ContentView: View { @State private var path = NavigationPath() @EnvironmentObject var authViewModel: AuthenticationViewModel @ObservedObject var vm = GoogleSignInButtonViewModel(style: .wide) var body: some View { // 将NavigationStack作为顶级视图,占据全屏 NavigationStack(path: $path) { VStack { // Logo等静态内容 Image(systemName: "logo") // 替换为你的Logo .font(.largeTitle) .padding() HStack { switch authViewModel.state { case .signedIn: // 登录状态下可显示加载指示器或空视图 ProgressView() case .signedOut: GoogleSignInButton(viewModel: vm, action: authViewModel.signIn) .accessibilityIdentifier("GoogleSignInButton") .accessibility(hint: Text("使用Google登录")) .padding() } } } .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color("Standard").ignoresSafeArea()) // 配置导航目标:路径添加"UserProfileView"时跳转至对应视图 .navigationDestination(for: String.self) { destination in if destination == "UserProfileView" { UserProfileView() .environmentObject(authViewModel) } } // 监听认证状态变化,登录成功后触发导航 .onChange(of: authViewModel.state) { newState in if newState == .signedIn { // 短暂延迟确保状态更新完成(可选,视情况调整) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { path.append("UserProfileView") } } } } } }
解决方案2:切换应用根视图(更适合主页面场景)
如果UserProfileView是登录后的主页面,无需返回登录页,可直接在App入口根据认证状态切换根视图:
@main struct YourAppName: App { // 初始化认证ViewModel @StateObject private var authViewModel = AuthenticationViewModel() var body: some Scene { WindowGroup { Group { if authViewModel.state == .signedIn { UserProfileView() .environmentObject(authViewModel) } else { ContentView() .environmentObject(authViewModel) } } } } }
此时ContentView只需保留登录按钮即可:
struct ContentView: View { @EnvironmentObject var authViewModel: AuthenticationViewModel @ObservedObject var vm = GoogleSignInButtonViewModel(style: .wide) var body: some View { VStack { // Logo等静态内容 Image(systemName: "logo") .font(.largeTitle) .padding() GoogleSignInButton(viewModel: vm, action: authViewModel.signIn) .accessibilityIdentifier("GoogleSignInButton") .accessibility(hint: Text("使用Google登录")) .padding() } .padding() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color("Standard").ignoresSafeArea()) } }
关键说明
- 方案1适合需要保留导航栈(比如允许用户返回登录页)的场景。
- 方案2更简洁,适合登录后直接进入主页面且无需返回的场景。
- 确保
UserProfileView本身是全屏布局(未嵌套在有限空间的容器中)。
内容的提问来源于stack exchange,提问作者revvy
相关产品推荐
相关产品推荐

