基于VIewModel状态更新SwiftUI视图?

基于VIewModel状态更新SwiftUI视图?,swift,swiftui,combine,Swift,Swiftui,Combine,我在SwiftUI视图中使用了@State进行设置,并在视图中执行了所有操作(加载API等),但是当尝试重新构造时,我不再使用@ViewBuilder和@State以及使用@ObservedObject视图模型,我无法根据@State变量动态更改视图 我的代码现在是 @ObservedObject private var contentViewModel: ContentViewModel init(viewModel: ContentViewModel) {

我在SwiftUI视图中使用了
@State
进行设置,并在视图中执行了所有操作(加载API等),但是当尝试重新构造时,我不再使用
@ViewBuilder
@State
以及使用
@ObservedObject
视图模型,我无法根据
@State
变量动态更改视图

我的代码现在是

    
    @ObservedObject private var contentViewModel: ContentViewModel
    
    init(viewModel: ContentViewModel) {
        self.contentViewModel = viewModel
    }
    
    var body: some View {
        if contentViewModel.isLoading {
            loadingView
        }
        else if contentViewModel.fetchError != nil {
            errorView
        }
        else if contentViewModel.movies.isEmpty {
            emptyListView
        } else {
            moviesList
        }
    }
但是,每当这些viewmodel属性发生更改时,视图都不会像我在类中将它们用作
@State
属性时那样更新

ViewModel如下所示:

final class ContentViewModel: ObservableObject {

    var movies: [Movie] = []
    var isLoading: Bool = false
    var fetchError: String?
    
    private let dataLoader: DataLoaderProtocol
    
    init(dataLoader: DataLoaderProtocol = DataLoader()) {
        self.dataLoader = dataLoader

        fetch()
    }

    func fetch() {
        isLoading = true
        dataLoader.loadMovies { [weak self] result, error in
            guard let self = `self` else { return }
            self.isLoading = false
            guard let result = result else {
                return print("api error fetching")
            }
            guard let error = result.errorMessage, error != "" else {
                return self.movies = result.items
            }
            return self.fetchError = error
        }
    }
既然这3个状态决定属性已抽象为viewmodel,如何将它们绑定到视图中


感谢在您的所有3处房产之前发布的Place@

 @Published var movies: [Movie] = []
 @Published var isLoading: Bool = false
 @Published var fetchError: String?
通过使类符合ObservieObject,您几乎做到了这一点,但它本身什么也不做。然后,您需要确保使用我在上面显示的
@Published
自动发送更新,或者手动发送
objectWillChange.send()

编辑:


另外,您应该知道,如果您将该数据向下传递给任何子对象,您应该将parents属性设置为
@StateObject
,并且子对象的属性设置为
ObservedObject

啊,太接近了!谢谢,关于如何处理此问题的任何建议“不允许从后台线程发布更改;请确保在模型更新时从主线程(通过诸如receive(on:))之类的运算符)发布值。”错误i未被抛出?是要避免此错误,请确保更新值时您在主线程上。。因此,无论您在哪里遇到错误,请将这一行代码包装在'DispatchQueue.main.async{//error code}中。在本例中,我会说它在fetch()方法中的某个地方。非常感谢您的帮助!