You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改ViewModel值后@Published未更新UI问题咨询

解决UIHostingController中SwiftUI视图不跟随@Published属性更新的问题

问题原因

  • 协议未支持Combine发布机制:原DashboardSceneViewModel协议里的homeJson只是普通属性,没有暴露@Published的发布特性,导致SwiftUI无法识别到属性变化。
  • 视图未监听ViewModel变化:DashboardSceneView里的viewModel是普通变量,没加@ObservedObject修饰,SwiftUI没法追踪属性更新来刷新视图。
  • ViewController存在初始化和赋值问题:原代码里viewModel是可选类型,且赋值时的viewModel.data = response是错误写法,应该更新homeJson,同时要确保View和Controller共享同一个ViewModel实例。

修复方案

1. 修改ViewModel协议,支持ObservableObject

让协议继承ObservableObject,并把homeJson标记为@Published,确保遵循协议的类具备发布属性变化的能力:

import Combine

protocol DashboardSceneViewModel: ObservableObject {
    var delegate: DashboardSceneViewDelegate? { get set }
    @Published var homeJson: Model? { get set }
}

class DefaultDashboardSceneViewModel: DashboardSceneViewModel {
    var delegate: DashboardSceneViewDelegate?
    @Published var homeJson: Model?
}

2. 视图中用@ObservedObject监听ViewModel

在DashboardSceneView里用@ObservedObject修饰viewModel,这样SwiftUI会自动监听@Published属性的变化并刷新视图:

struct DashboardSceneView: View {
    @ObservedObject var viewModel: DashboardSceneViewModel
    
    var body: some View {
        VStack {
            if let homeJson = viewModel.homeJson {
                Text(homeJson.header ?? "")
            }
            Button("Tap"){
                print("按钮点击")
            }
        }
    }
}

3. 修正ViewController的初始化和赋值逻辑

初始化时直接传入ViewModel实例,确保View和Controller共享同一个对象,同时修正赋值方法:

final class DashboardSceneViewController: UIHostingController<DashboardSceneView> {
    private let viewModel: DashboardSceneViewModel
    
    init(viewModel: DashboardSceneViewModel) {
        self.viewModel = viewModel
        super.init(rootView: DashboardSceneView(viewModel: viewModel))
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func updateViewModel(with response: Model) {
        viewModel.homeJson = response
    }
}

关键说明

  • 协议继承ObservableObject后,遵循类会自动拥有objectWillChange发布者,配合@Published可以让SwiftUI感知属性变化。
  • @ObservedObject专门用于监听外部传入的引用类型ViewModel,属性更新时会自动触发视图刷新。
  • 初始化ViewController时直接传入ViewModel实例,避免可选类型的空值问题,保证View和Controller操作的是同一个ViewModel。

内容的提问来源于stack exchange,提问作者user968597

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:54:18