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

SwiftUI中ObservedObject绑定值不更新,MVVM模式实现故障排查

问题根因

所有子视图中接收ViewModel的属性未添加@ObservedObject修饰符,导致子视图无法订阅ViewModel的状态变更通知,即使ViewModel的@Published属性发生变化,子视图也不会触发界面重绘。

修复步骤
  1. 给所有子视图的ViewModel属性添加@ObservedObject修饰符,让子视图可以监听ViewModel的状态变化
  2. (iOS14+优化建议)父视图中自行创建持有的ViewModel建议改用@StateObject修饰,避免视图刷新时ViewModel被意外重建
  3. (写法优化)不需要在Button的label内额外加onTapGesture处理点击,直接把交互逻辑写在Button的action参数中即可,避免出现手势优先级冲突
  4. (命名规范优化)ViewModel类名遵循Swift大驼峰命名规范,改为SetHeightViewModel
关键修改代码示例

所有子视图统一修改逻辑(以ModeArea为例,其他子视图同理)

// 修改前
struct ModeArea: View {
    var viewModel: setHeightViewModel
    // 其余代码不变
}

// 修改后
struct ModeArea: View {
    @ObservedObject var viewModel: SetHeightViewModel
    // 其余代码不变
}

父视图修改示例(iOS14+适用)

struct ViewSetHeight: View {
    // 修改前
    // @ObservedObject var setHeightVM = setHeightViewModel()
    // 修改后
    @StateObject var setHeightVM = SetHeightViewModel()
    // 其余代码不变
}

按钮写法优化示例

// 修改前
Button(action: {
    print("Imperial Tapped")
}, label: {
    Text("Imperial").onTapGesture {
        viewModel.toggleMode()
    }
})

// 修改后
Button {
    print("Imperial Tapped")
    viewModel.toggleMode()
} label: {
    Text("Imperial")
}

修改完成后点击按钮,ViewModel的状态变更就会通知所有订阅了它的子视图触发重绘,界面就会同步更新数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:57:02