SwiftUI 中如何在父视图中重新初始化 StateObject 实例?
解决方案
你可以从两种实现思路里选最适配你业务场景的:
方案1:每次弹出训练页时生成全新的WorkoutManager实例(推荐,完全无历史残留)
不需要修改WorkoutView的逻辑,只要调整ContentView的实例初始化时机,保证每次打开Sheet都是全新的干净实例:
struct ContentView: View { // 仅声明,不提前初始化实例 @StateObject var workoutManager: WorkoutManager? @State var showingWorkoutView = false var body: some View { Button { // 每次点击开始训练时生成全新实例 workoutManager = WorkoutManager() showingWorkoutView.toggle() } label: { Text("Start Workout") } .sheet(isPresented: $showingWorkoutView) { // Sheet关闭后销毁旧实例 workoutManager = nil } content: { if let workoutManager = workoutManager { WorkoutView(showingWorkoutView: $showingWorkoutView) .environmentObject(workoutManager) } } } }
方案2:给WorkoutManager加重置方法,手动清理状态
如果你不需要完全销毁实例,仅需要清理训练相关的历史状态,可以给WorkoutManager新增重置方法:
- 先扩展
WorkoutManager,新增重置逻辑:
class WorkoutManager: ObservableObject { var workout: HKWorkout? // 其他训练相关状态属性 func resetState() { workout = nil // 所有需要清空的历史状态都在此处恢复为初始值 } }
- 在结束训练时调用重置方法即可:
struct WorkoutView: View { @EnvironmentObject var workoutManager: WorkoutManager @Binding var showingWorkoutView: Bool var body: some View { Text("Workout Started") .padding() Button { workoutManager.resetState() showingWorkoutView.toggle() } label: { Text("End Workout") } } }
注意:如果你的
WorkoutManager属性变化需要驱动视图刷新,记得给对应属性加上@Published包装器。
内容的提问来源于stack exchange,提问作者GarySabo
相关产品推荐
相关产品推荐

