英文:
Push user to a logged in view not working
问题
对于iOS 16+,我在ContentView上使用Google Sign In按钮来认证用户。如果用户未经过身份验证,按钮将显示,用户可以进行身份验证过程。一旦经过身份验证,用户将返回到ContentView,该视图还会检查用户是否已登录。如果是的话,我们将用户发送到主应用程序,例如UserProfileView。
我的代码如下。当用户登录时,UserProfileView会在ContentView内部呈现,而不是将用户发送到全新的视图。我尝试了各种方法,但无法弄清楚如何做到这一点。
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 {
VStack {
//一些带有标志等的代码
HStack {
switch authViewModel.state {
case .signedIn:
let _ = print("用户已登录")
NavigationStack(path: $path) {
Text("")
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
path.append("UserProfileView")
}
}
case .signedOut:
let _ = print("用户已登出")
GoogleSignInButton(viewModel: vm, action: authViewModel.signIn)
.accessibilityIdentifier("GoogleSignInButton")
.accessibility(hint: Text("使用Google登录的按钮。"))
.padding()
}
}
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color("Standard").ignoresSafeArea(.all, edges: .all))
}
}
用户在登录之前的ContentView:
用户在登录后的ContentView;请注意,UserProfileView在ContentView内部呈现(原来的Google Sign In按钮所在的位置),而不是导航到占据整个屏幕的UserProfileView。
UserProfileView - 用户在登录后应该从ContentView重定向到这里。如下所示的UserProfileView占据了整个屏幕,这正是我想要的。
希望能得到一些帮助。
英文:
For iOS16+, I am using Google Sign In button on ContentView to authenticate users. If users are not authenticated, the button shows and user can go through the authentication process. Once authenticated, user is brought back to ContentView that also checks if user has been signed in. If so, we send the user to main app, say UserProfileView.
My code is as follows. When the user is signed in, UserProfileView renders inside ContentView rather than sending the user new a completely new view. I've tried various ways but can't figure out how to do so.
import SwiftUI
import GoogleSignIn
import GoogleSignInSwift
struct ContentView: View {
//some vars declared
@State private var path = NavigationPath()
@EnvironmentObject var authViewModel: AuthenticationViewModel
@ObservedObject var vm = GoogleSignInButtonViewModel(style: .wide)
var body: some View {
VStack {
//some code with logo etc
HStack {
switch authViewModel.state {
case .signedIn:
let _ = print("User is signed in")
NavigationStack(path: $path) {
Text("")
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
path.append("UserProfileView")
}
}
case .signedOut:
let _ = print("User is signed out")
GoogleSignInButton(viewModel: vm, action: authViewModel.signIn)
.accessibilityIdentifier("GoogleSignInButton")
.accessibility(hint: Text("Sign in with Google button."))
.padding()
}
}
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color("Standard").ignoresSafeArea(.all, edges: .all))
}
ContentView before user signs in:
ContentView after user signs in; note the UserProfileView renders inside the ContentView (where the Google Sign In button used to be), rather than navigating to a UserProfileView that takes up the entire screen.
UserProfileView - user should be directed from ContentView to here upon login. UserProfileView as shown below takes up the whole screen, which is what I want.
Would appreciate some help here.
答案1
得分: 0
以下是代码的翻译部分:
enum SignInState {
case signedIn, signedOut
}
struct ContentView: View {
@State var state: SignInState
var body: some View {
switch state {
case .signedOut:
SignInView(state: $state)
case .signedIn:
NavigationStack {
UserProfileView()
}
}
}
}
struct SignInView: View {
@Binding var state: SignInState
var body: some View {
VStack {
Rectangle()
.frame(width: 300, height: 400)
Button("登录") {
state = .signedIn
}
.buttonStyle(.borderedProminent)
.padding()
Spacer()
}
.frame(maxWidth: .infinity)
.background(.mint, ignoresSafeAreaEdges: .all)
.navigationTitle("登录")
}
}
struct UserProfileView: View {
var body: some View {
Text("用户资料")
.navigationTitle("用户资料")
}
}
请注意,我已将 "Sign in" 和 "User Profile" 等内容翻译成了中文。如果您需要任何进一步的帮助,请随时告诉我。
英文:
How about this, just using a SignInState
enum to switch between views:
enum SignInState {
case signedIn, signedOut
}
struct ContentView: View {
@State var state: SignInState
var body: some View {
switch state {
case .signedOut:
SignInView(state: $state)
case .signedIn:
NavigationStack {
UserProfileView()
}
}
}
}
struct SignInView: View {
@Binding var state: SignInState
var body: some View {
VStack {
Rectangle()
.frame(width: 300, height: 400)
Button("Sign in") {
state = .signedIn
}
.buttonStyle(.borderedProminent)
.padding()
Spacer()
}
.frame(maxWidth: .infinity)
.background(.mint, ignoresSafeAreaEdges: .all)
.navigationTitle("Sign in")
}
}
struct UserProfileView: View {
var body: some View {
Text("User Profile")
.navigationTitle("User Profile")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论