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 视图未更新