如何在SwiftUI中通过ViewModel传播模型更改



我试图理解SwiftUI中的MVVM模式,但我并不完全理解ViewModel是如何侦听和传播Model对象中的更改的。许多例子,包括苹果公司的这个例子,都谈到了让Model从ObservableObject继承并直接在视图中使用它。这是有道理的。

但是,ViewModel观察其基础模型更改的最佳/推荐方式是什么?

一个简单的例子是显示小部件的titleWidgetView,但例如,title可以从后台网络调用在后台更改。

class WidgetView: View {
@ObservedObject var widgetVM = WidgetViewModel()
var body: some View {
Text(widgetVM.title)
}
}
class WidgetViewModel : ObservableObject {
var widget: Widget
var title: String {
get {
// Some translation to the title for this particular view
return widget.title + "!"
}
}
}
struct Widget {
// Some other timer or background process is changing the title
var title: String
}

我探索过的一个粗略的解决方案是使用一个单独的title并侦听更改。因此,如果WidgetObservableObject@Published扩展到title字段,则WidgetViewModel可以执行以下操作:

class WidgetViewModel : ObservableObject {
var widget: Widget
@Published var title: String = ""
var cancellable: AnyCancellable?
init() {
self.cancellable = widget.$title.receive(on: DispatchQueue.main)
.sink(receiveValue: self.updateTitle )
}
func updateTitle(_: String) {
self.title = widget.title + "!"
}
}

Widget是否也推荐/标准扩展ObservableObject?如果是,WidgetViewModel如何正确传递更改通知?WidgetModelView.widget似乎需要同时是@Published和@ObservedObject,但这似乎不对。

这里有人有什么见解吗?

您的Widget是struct,所以它不能是ObservableObject,相反,您可以执行以下

class WidgetViewModel : ObservableObject {
var widget: Widget {
didSet {
updateTitle(widget)    // << here !!
}
}
@Published var title: String = ""
func updateTitle(_: String) {
self.title = widget.title + "!"
}
}

最新更新