SwiftUI 如何在视图关闭后更新变量同步状态
SwiftUI 关闭全屏子视图后计数不更新问题修复
核心错误原因
两个视图中各自创建了完全独立的UserProgress实例,状态没有同步:
- 父视图
DataUpdateView通过@StateObject var progress = UserProgress()创建了第一个进度实例,自身的Text组件监听这个实例的score变化 - 子视图
DataUpdateView2中写@ObservedObject var progress = UserProgress()会初始化第二个全新的进度实例,点击返回时修改的是第二个实例的score值,父视图完全感知不到变化,因此UI不会更新。
修复方法
不要在子视图中重新创建ObservableObject实例,把父视图持有的同一个progress实例传递给子视图即可。
具体修改点
- 修改子视图的progress声明,删除默认初始化逻辑,仅保留类型标注:
struct DataUpdateView2: View { @ObservedObject var progress: UserProgress // 删掉后面的= UserProgress() @Environment(\.presentationMode) var presentationMode // 其余代码不变 } - 父视图弹出全屏覆盖层时,传入自身持有的progress实例:
.fullScreenCover(isPresented: $nextView, content: { DataUpdateView2(progress: progress) // 传入实例 })
修复后完整代码
import SwiftUI class UserProgress: ObservableObject { @Published var score = 0 } struct DataUpdateView: View { @State var nextView = false @StateObject var progress = UserProgress() var body: some View { VStack { Text("Score Count \(progress.score)") Text("Next View") .onTapGesture { nextView = true } .fullScreenCover(isPresented: $nextView) { DataUpdateView2(progress: progress) } } } } struct DataUpdateView2: View { @ObservedObject var progress: UserProgress @Environment(\.presentationMode) var presentationMode var body: some View { Text("Back") .onTapGesture { progress.score += 1 presentationMode.wrappedValue.dismiss() } } }
属性使用说明
@StateObject:当前视图是ObservableObject实例的持有者,负责实例的初始化和生命周期管理,适合用在数据源的创建位置@ObservedObject:当前视图仅作为ObservableObject的观察者,不负责实例创建,必须由外部传入已初始化好的实例才能正常监听状态变化- 若后续需要跨3层以上视图共享同一份状态,可以使用
@EnvironmentObject做视图层级注入,无需逐层传参,适配更复杂的业务场景。
内容的提问来源于stack exchange,提问作者user1591668
相关产品推荐
相关产品推荐

