ObservedObject 未触发视图重绘

Posted

技术标签:

【中文标题】ObservedObject 未触发视图重绘【英文标题】:ObservedObject not triggering view redraw 【发布时间】:2020-10-01 14:10:31 【问题描述】:

我有一个需要从 api 获取数据的视图。 我对 SwiftUI 的理解是,通过使用 onAppear,将调用 api,更新 viewmodel 属性,并更改 StateObject,这将触发 View 重绘。

问题是没有进行重绘。

我可以看到一个api调用发生了,并且在使用解码数据后添加调试我可以看到返回了很多数据。

我删除了很多代码以使逻辑更易于理解(如下)。

用@ObservedObject 替换@StateObject 并从父级传递到视图中也没有区别。

谢谢

struct FactoryDetailView: View 

  var factory: Factory
  @StateObject var factoryDetailsViewModel: FactoryDetailsViewModel()

  var body: some View 

     VStack 
        Text(factory.name)
        ForEach(factoryDetailsViewModel.details)  det in
          Text(det)
        
     
     .onAppear  factoryDetailsViewModel.loadDetails(factory) 
  

视图模型:

class FactoryDetailsViewModel: ApiViewModel 
  @Published var details: [ String ]
  func loadDetails(factory: Factory) 

     // Do api call...

     self.objectWillChange.send()
     self.details = decodedResultsFromApiCall
     self.objectWillChange.send()

class ApiViewModel: ObservableObject 

【问题讨论】:

【参考方案1】:

嗯...删除的细节可能是问题的原因,但一般方法应该如下所示

struct FactoryDetailView: View 
  ...
  // assume it is a type and here there is initialization 
  @StateObject var factoryDetailsViewModel = FactoryDetailsViewModel()
  ...

现在关于self.objectWillChange.send() - 不要调用它,修改发布的属性它会自动调用

func loadDetails(factory: Factory) 

     // Do api call...
      
          // this is inside (!) API callback
          DispatchQueue.main.async 
             // update published property on main queue, always.
             self.details = decodedResultsFromApiCall
          
     

【讨论】:

谢谢。我刚刚发现,如果我删除 '@Published' 它可以工作,但需要 objectWillChange.send() 调用。我猜在某些情况下您不能使用“@Published”包装器。我试图避免手动调用 objectWillChange,因为这似乎违背了它应该完成的方式。【参考方案2】:

这有答案:

@Published property wrapper not working on subclass of ObservableObject

我看到的问题是相同的 - 子类化 ObservableObject。

我现在有了一个解决方案,通过父类中的“@Published var api_response”并从子类的属性中删除@Published(尽管在其中留下“@Published”似乎不会造成任何副作用,所以它们如果只是为了记录意图,也可以保留)。

感谢您的回复。

【讨论】:

以上是关于ObservedObject 未触发视图重绘的主要内容,如果未能解决你的问题,请参考以下文章

成功登录后,SwiftUI ObservedObject 未更新视图

@ObservedObject 更改后 SwiftUI 视图未更新

TabView 在重绘时是不是会错过导航点击?

UITextView 的 SwiftUI Wrapper 未更新 ObservedObject

触发drawRect重绘视图的按钮

宽度约束更新后视图未重绘