我想根据条件改变ContentViews环境对象


import SwiftUI
import Firebase
@main
struct TSUDateApp: App {

@AppStorage(CurrentUserDefaults.userID) var currentUserID: String?


init() {
FirebaseApp.configure()
}

var body: some Scene {
WindowGroup {
if currentUserID != nil {
ContentView().environmentObject(AuthViewModel())
.environmentObject(MessageListVM(userID: currentUserID!))
} else {
ContentView().environmentObject(AuthViewModel())
}
}
}
}

我想根据条件改变ContentViews环境对象,但它只迭代一次,如果currentUserID改变,它不会更新,如果我想获得逻辑,我想我必须重新加载应用程序,而不是它正在工作。我试过.onReceive.onChange,但总是失败。

我在这里改变signOut()函数中的currentUserID

func signOut() {
navigateToLoginView()

let defaultsDictionary = UserDefaults.standard.dictionaryRepresentation()
defaultsDictionary.keys.forEach { key in
UserDefaults.standard.removeObject(forKey: key)
}

try? Auth.auth().signOut()
}

问题是,@AppStorage不刷新您的视图,如果有东西改变UserDefaults通过任何其他方法,甚至另一个AppStorage与相同的键。

在这种情况下,最简单的解决方案是将currentUserID移动到viewmodel之一。由于您在这两种情况下都使用AuthViewModel,因此这似乎是适合此的容器。
class AuthViewModel: ObservableObject{
@AppStorage("currentUserID") var currentUserID: String?
}
struct TSUDateApp: App {
@StateObject private var authViewModel = AuthViewModel()
var body: some Scene {
WindowGroup {
if let currentUserID = authViewModel.currentUserID{
ContentView()
.environmentObject(authViewModel)
.environmentObject(MessageListVM(userID: currentUserID))
} else {
ContentView().environmentObject(authViewModel)
}
}
}
}

signOut函数看起来像这样:

func signOut() {
navigateToLoginView()

authViewModel.currentUserId = nil

try? Auth.auth().signOut()
}

当然你需要先把它从环境中拉出来:

@EnvironmentObject private var authViewModel: AuthViewModel

另一种方法是将currentUserID作为Binding传递给ContentView:

struct TSUDateApp: App {

@AppStorage("currentUserID") var currentUserID: String?

var body: some View{
if let currentUserID = currentUserID{
ContentView(currentUserID: $currentUserID)
.environmentObject(AuthViewModel())
.environmentObject(MessageListVM(userID: currentUserID))
} else {
ContentView(currentUserID: $currentUserID).environmentObject(AuthViewModel())
}
}
}

ContentView中创建绑定并在signOut中操作。

@Binding var currentUserID: String?
func signOut() {
navigateToLoginView()
currentUserId = nil
try? Auth.auth().signOut()
}

最新更新