为了在成功登录后从我的根视图显示我的内容,我尝试使用ObservedObject
和EnvironmentObject
,但无济于事。
例如如下:
struct RootView: View {
@EnvironmentObject var loginManager: LoginManager
var body: some View {
Group {
if loginManager.isLoggedIn {
SegmentedView()
}
else {
WelcomeView()
}
}
}
}
class LoginManager: ObservableObject {
static let shared = LoginManager()
var cancellable = Set<AnyCancellable>()
@Published var isLoggedIn = false
...
func login(...) {
...
// on success
self.isLoggedIn = true
}
LoginManager
保留在环境中SceneDelegate
并放入环境中:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var loginManager = LoginManager.shared
...
// the view passed to window.rootUiewController via UIHostingController
let contentView = RootView().environmentObject(loginManager)
登录后,它会直接回到我的WelcomeView
. 我错过了什么?
编辑
这是一个新的方面。我有一个视图模型LoginView
来管理日期字段中的数据。当登录按钮被按下时,我login()
在这个视图模型中调用一个方法。
我需要.sink
在视图模型中进行两个回调,因为我必须通过将loading
标志设置为 false 来关闭加载指示器。
所以我不能self.isLoggedIn = true
直接调用,因为我在视图模型中,而不是LoginManager
. 相反,我打电话
self.loginManager.isLoggedIn = true
我怀疑这条线不起作用。
视图模型和登录管理器之间的连接是这样完成的
@ObservedObject var loginManager = LoginManager.shared
但是,在将其转移到 之后LoginManager
,我确实是self.isLoggedIn
从那里打电话的。它仍然无法正常工作。
我有两篇论文:
可能是视图没有正确设置
Group
等。我也尝试使用@ViewBuilder
等,没有区别。可能以某种方式存在两个实例
LoginManager
,或者以RootView
某种方式重新初始化了一个新实例,其中isLoggedIn
为假。但我多年来一直在创建这样的 Swift 单例:静态让共享 = LoginManager()
从来没有任何问题。
正如评论中提到的,我在全部切换到时遇到了另一个错误@EnvironmentObject
:
Fatal error: No ObservableObject of type LoginManager found. A View.environmentObject(_:) for LoginManager may be missing as an ancestor of this view.: file SwiftUI, line 0