firebase - SwiftUI 在使用 Firebase 单击注销时隐藏 TabView
问题描述
我是一个带有 Firebase 登录/注销的简单应用程序。登录工作完美,当我注销 LoginView 时出现我的应用程序,但问题是 TabView 仍然存在,您可以导航到另一个选项卡。那么应该发生什么:标签栏应该是不可见/隐藏的,或者我的 LoginView 应该出现在其他所有内容上。
内容视图.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")
}
}
}
登录视图.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@*/)
}
}
}
解决方案
您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
级别处理。
推荐阅读
- python - python - 如何在python选项卡内使用plotly-dash按钮触发函数?
- oauth-2.0 - 索引 244 处的非法查询
- python - 为什么在 Linux 的 Windows 子系统中 pip3 install multiprocessing 失败?
- python - 使用“缩放到矩形”选项放大 matplotlib 时图形大小发生变化
- c# - 如何通过 .NET Framework 应用程序以编程方式检查我的计算机上安装的 .NET Core 运行时版本?
- asp.net - 在 IE/Net webbrowser 中使用 Angular 项目
- elasticsearch - Elasticsearch 的索引生命周期管理随机删除索引
- python-3.x - 您如何为 Zoom.us 会议发送隐藏字幕?
- python - Python peewee.ImproperlyConfigured:未安装 MySQL 驱动程序
- .net - Bootstrap:在 2500px 宽的浏览器窗口中使用 container-fluid 时,col-lg 确定 col-xl 的宽度