SwiftUI中ObservedObject绑定值不更新,MVVM模式实现故障排查
问题根因
所有子视图中接收ViewModel的属性未添加@ObservedObject修饰符,导致子视图无法订阅ViewModel的状态变更通知,即使ViewModel的@Published属性发生变化,子视图也不会触发界面重绘。
修复步骤
- 给所有子视图的ViewModel属性添加
@ObservedObject修饰符,让子视图可以监听ViewModel的状态变化 - (iOS14+优化建议)父视图中自行创建持有的ViewModel建议改用
@StateObject修饰,避免视图刷新时ViewModel被意外重建 - (写法优化)不需要在Button的label内额外加
onTapGesture处理点击,直接把交互逻辑写在Button的action参数中即可,避免出现手势优先级冲突 - (命名规范优化)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
相关产品推荐
相关产品推荐

