0

我有一个类似于以下(简化)代码的应用程序架构。我使用WorkoutManager StateObject我在设置视图中初始化的 a,然后通过EnvironmentObject. 问题是,在解除后,.sheet没有任何生命周期事件可以初始化一个 new WorkoutManager,我需要它才能连续开始新的锻炼。在下面的示例中,我如何WorkoutView能够重新初始化 WorkoutManager 使其成为一个干净的对象?

import SwiftUI
import HealthKit

class WorkoutManager: ObservableObject {
    
    var workout: HKWorkout?
}

struct ContentView: View {
    
    @StateObject var workoutManager = WorkoutManager()
    
    @State var showingWorkoutView = false
    
    var body: some View {
      
        Button {
            showingWorkoutView.toggle()
        } label: {
            Text("Start Workout")
        }
        .sheet(isPresented: $showingWorkoutView) {
            WorkoutView(showingWorkoutView: $showingWorkoutView)
        }
        
    }
}

struct WorkoutView: View {
    
    @EnvironmentObject var workoutManager:  WorkoutManager
    @Binding var showingWorkoutView: Bool
    
    var body: some View {
        Text("Workout Started")
            .padding()
        Button {
            showingWorkoutView.toggle()
            //Here I want to initialize a new WorkoutManager to clear out the previous workout's state, how? 
        } label: {
            Text("End Workout")
        }

    }
}
4

1 回答 1

2

正如评论中已经提到的,您可能想要采取的路线是在同一WorkoutManager. 无论如何,您都无法将对象分配给 a - 由于' 的不可变@StateObject,您最终会遇到编译器错误。Viewself

其次,我建议您可能不想依赖ButtoninWorkoutView来执行此操作。例如,如果用户sheet通过滑动关闭了,则不会被调用。相反,您可以监听sheet的状态onChange(另一种方法是使用 的onDismiss参数sheet):

class WorkoutManager: ObservableObject {
    var workout: HKWorkout?
    
    func resetState() {
        //do whatever you need to do to reset the state
        print("Reset state")
    }
}

struct ContentView: View {
    
    @StateObject var workoutManager = WorkoutManager()
    
    @State var showingWorkoutView = false
    
    var body: some View {
      
        Button {
            showingWorkoutView.toggle()
        } label: {
            Text("Start Workout")
        }
        .sheet(isPresented: $showingWorkoutView) {
            WorkoutView(showingWorkoutView: $showingWorkoutView)
        }
        .onChange(of: showingWorkoutView) { newValue in
            if !newValue {
                workoutManager.resetState()
            }
        }
    }
}

struct WorkoutView: View {
    
    @EnvironmentObject var workoutManager:  WorkoutManager
    @Binding var showingWorkoutView: Bool
    
    var body: some View {
        Text("Workout Started")
            .padding()
        Button {
            showingWorkoutView.toggle()
        } label: {
            Text("End Workout")
        }

    }
}
于 2021-11-08T00:42:52.617 回答