SwiftUI 在使用 Firebase 单击注销时隐藏 TabView

Posted

技术标签:

【中文标题】SwiftUI 在使用 Firebase 单击注销时隐藏 TabView【英文标题】:SwiftUI hide TabView when clicking Logout with Firebase 【发布时间】:2021-02-11 09:05:56 【问题描述】:

我是一个带有 Firebase 登录/注销的简单应用。登录完美运行,当我注销 LoginView 时,我的应用程序显示出来,但问题是 TabView 仍然存在,您可以导航到另一个选项卡。那么应该发生什么:标签栏应该是不可见/隐藏的,或者我的 LoginView 应该出现在其他所有内容之上。

ContentView.swift

    var body: some View 
        if Auth.auth().currentUser == nil 
            LoginView()
        
        else 
            AppView()
        
    

AppView.swift

var body: some View 
    TabView 
        PlacesView()
            .tabItem 
                Image(systemName: "mappin.and.ellipse")
                Text("Places")
            
        MeetupsView()
            .tabItem 
                Image(systemName: "person.3")
                Text("Meetups")
            
        ProfileView()
            .tabItem 
                Image(systemName: "person.crop.circle")
                Text("Profile")
            
        SettingsView()
            .tabItem 
                Image(systemName: "gear")
                Text("Settings")
            
    

LoginView.swift

@State var signInSuccess = false

var body: some View 
    return Group 
        if signInSuccess 
            AppView()
        
        else 
            LoginFormView(signInSuccess: $signInSuccess)
        
    

设置退出

NavigationView 
            if !signedIn 
                ContentView()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                    .background(Color.red)
                    .edgesIgnoringSafeArea(.all)
            
            else 
            List 
    Button(action: 
                    do 
                      try Auth.auth().signOut()
                        signedIn.toggle()
                     catch let signOutError as NSError 
                      print ("Error signing out: %@", signOutError)
                    
                    
                )
                Text("Sign out")
                    .fontWeight(.light)
                        .foregroundColor(Color.red)
                        .frame(maxWidth: .infinity, alignment: .center)
                    .font(/*@START_MENU_TOKEN@*/.title2/*@END_MENU_TOKEN@*/)
                
          
     

看起来像

【问题讨论】:

【参考方案1】:

您的ContentView 不知道会触发对视图层次结构的更新,因为目前它无法理解 Auth.auth().currentUser 在用户注销时更改了值。

一种解决方案是使用 @ObservableObject 和 Firebase 的身份验证状态侦听器为您处理此问题:

class AuthManager : ObservableObject 
    @Published var isLoggedIn = false
    
    private var authStateHandle: AuthStateDidChangeListenerHandle?
    
    init() 
        authStateHandle = Auth.auth().addStateDidChangeListener  _, user in
            self.isLoggedIn = user != nil
        
    

然后,在 ContentView 中:

struct ContentView : View 
  @ObservedObject authManager = AuthManager()
  var body : some View 
    if authManager.isLoggedIn 
      AppView()
     else 
      LoginView()
    
  

Firebase 提供的身份验证状态侦听器句柄的好处是它自动处理连接到全局 Auth() 实例,因此您甚至无需担心将其连接到您的登录或注销功能。这意味着您可能可以删除登录视图上的 signInSuccess 布尔检查,因为现在将在 ContentView 级别处理。

【讨论】:

以上是关于SwiftUI 在使用 Firebase 单击注销时隐藏 TabView的主要内容,如果未能解决你的问题,请参考以下文章

如何使用firebase auth android无法返回android

AngularFire2:通过多个浏览器选项卡通知注销

点击注销时 SwiftUI 将应用程序重置为登录屏幕

如何在flutter上使用firebase正确实现注销

如何在 Firebase 3.0 中注销用户?

Firebase:注销后登录卡在加载中