当从另一个 ObservedObject 链接到 Published 属性时,视图不会对更改做出反应
Posted
技术标签:
【中文标题】当从另一个 ObservedObject 链接到 Published 属性时,视图不会对更改做出反应【英文标题】:View not reacting to changes of Published property when its chained from another ObservedObject 【发布时间】:2021-12-03 07:14:05 【问题描述】:下面是拥有 ViewModel 的 SwiftUI 视图,逻辑是如果 viewModel.authenticationService.user
包含用户对象,那么它将显示 HomeView,否则将要求登录。所以最初 viewModel.authenticationService.user
是 nil 并且用户登录成功,用户对象不再是 nil。
查看
struct WelcomeView: View
@ObservedObject private var viewModel: WelcomeView.Model
@State private var signInActive: Bool = false
init(viewModel: WelcomeView.Model)
self.viewModel = viewModel
var body: some View
if viewModel.authenticationService.user != nil
HomeView()
else
LoginView()
视图模型
extension WelcomeView
final class Model: ObservableObject
@ObservedObject var authenticationService: AuthenticationService
init(authenticationService: AuthenticationService)
self.authenticationService = authenticationService
身份验证服务
final class AuthenticationService: ObservableObject
@Published var user: User?
private var authenticationStateHandle: AuthStateDidChangeListenerHandle?
init()
addListeners()
private func addListeners()
if let handle = authenticationStateHandle
Auth.auth().removeStateDidChangeListener(handle)
authenticationStateHandle = Auth.auth()
.addStateDidChangeListener _, user in
self.user = user
static func signIn(email: String, password: String, completion: @escaping AuthDataResultCallback)
if Auth.auth().currentUser != nil
Self.signOut()
Auth.auth().signIn(withEmail: email, password: password, completion: completion)
但是,当用户对象更新了某个值时,它不会更新视图。我不确定,因为我是反应式编程方式的新手。有一个 View -> ViewModel -> Service 链,并且发布的用户属性在 Service 类中,一旦用户登录,就会成功更新。
我是否需要在 ViewModel 中添加一个监听器来响应服务发布的属性?或者有什么直接的方法可以让这个场景工作并更新 UI?
【问题讨论】:
我猜 User 是一个类而不是一个结构,对吧?由于类是引用类型,@published 属性包装器不会注意到用户对象内的变化。 ObservedObject 包装器在类中不起作用。您可以使用 sink 和 ant cancelable 获取更新 【参考方案1】:如果存在来自 View -> ViewModel -> Services 的链的情况:
@ObservedObject
不适用于课程。仅适用于 SwiftUI 视图(结构)。因此,如果您想通过服务观察视图模型的变化,您需要手动监听/订阅它。
self.element.$value.sink(
receiveValue: [weak self] _ in
self?.objectWillChange.send()
)
您也可以使用.assign
。了解更多详情here
【讨论】:
以上是关于当从另一个 ObservedObject 链接到 Published 属性时,视图不会对更改做出反应的主要内容,如果未能解决你的问题,请参考以下文章
仅当从另一个查询中选择时,SQL Select 语句才突然检索错误值
当从另一个控制器(弹出窗口)访问 UILabel(作为一个插座)时,它仍然为零
当从另一个 ViewController 类调用方法时,Xcode 找到一个 nil 变量,其中不应该是任何变量