SwiftUI 已发布更新不刷新

Posted

技术标签:

【中文标题】SwiftUI 已发布更新不刷新【英文标题】:SwiftUI Published updates not refreshing 【发布时间】:2020-12-08 07:13:39 【问题描述】:

我正在尝试通过一系列嵌套类来管理用户状态。

应用程序的基本视图使用globalState 环境对象。该对象允许用户进出其他视图。

@EnvironmentObject var globalState: GlobalState

// View Code
Text("Logged In").opacity(globalState.user.isLoggedIn ? 1 : 0)
Text("Please Sign In").opacity(globalState.user.isLoggedIn ? 0 : 1)

那么GlobalState 类仅包含User 类。 user 字段在其他地方初始化(不,我没有引用不同的 user 对象)。

class GlobalState: ObservableObject 
    @Published public var user: User // Inited somewhere else

class User 
    @Published var isLoggedIn: Bool = false

User 类在 inited 时自动提取有关用户的数据。在应用启动时,从钥匙串(如果存在)中提取用户信息。如果可以从现有数据创建用户,则该用户的isLoggedIn 设置为true

我知道我没有重复的对象,因为GlobalState 的查看代码中的globalState.user 的内存地址与为用户更新isLoggedIn 时的内存地址相同。

我通过使用两个级别的@Published 变量感到原力受到干扰,但一切都应该解决吗?

GlobalState 中的视图代码并没有更新。有谁知道为什么?一些我缺少的组合柔术?

【问题讨论】:

【参考方案1】:

ObservedObject 仅观察一级已发布属性,如果您有 ObservableObject 实例的层次结构,则需要为每个此类情况使用自己的 ObservedObject 分隔依赖视图。

@EnvironmentObject var globalState: GlobalState

// View Code - separated explicit subview
UserLoginStateView(user: globalState.user)

struct UserLoginStateView: View 
   @ObservedObject var user: User

   var body: some View 
      Group 
         Text("Logged In").opacity(user.isLoggedIn ? 1 : 0)
         Text("Please Sign In").opacity(user.isLoggedIn ? 0 : 1)
      
   

【讨论】:

【参考方案2】:

@Published 发布值更改,因此如果您替换 User 对象,它将更新。由于 User 是一个类(引用类型),当 User.isLoggedIn 发生变化时,它不会更新 GlobalState.user 的值。

解决此问题的是this package called NestedPublished,它将嵌套的 ObservableObject.willChange 发送到其父级。

【讨论】:

这对我来说非常有效。完成这项工作所需的重构最少。

以上是关于SwiftUI 已发布更新不刷新的主要内容,如果未能解决你的问题,请参考以下文章

已发布/观察到的 var 在视图 swiftui 中未更新,带有调用函数

在其他屏幕中更新绑定后,SwiftUI 列表行未刷新

swiftUI:设置更改后更新文本

SwiftUI 小部件无法刷新

SwiftUI 中已发布的计算属性未更新

已发布的属性未在 SwiftUI 中更新