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

iOS16+ Google登录后无法跳转至全屏UserProfileView问题求助

问题原因

你的代码存在两个核心问题导致UserProfileView内嵌在ContentView中:

  1. NavigationStack嵌套错误:你在signedIn分支内创建了新的NavigationStack,这个栈是ContentView的VStack/HStack子视图,仅占用局部空间,因此跳转后的UserProfileView会被限制在该区域内。
  2. 缺少导航目标配置:未为NavigationStack设置navigationDestination,明确指定路径添加特定值时应显示的视图。
解决方案1:使用根NavigationStack实现跳转

调整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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:56:08