SwiftUI:如何在父视图中初始化新的StateObject



我有一个类似于下面(简化(代码的应用程序架构。我使用一个WorkoutManagerStateObject,我在设置视图中初始化它,然后通过EnvironmentObject传递给它的子级。问题是,在取消.sheet后,没有任何生命周期事件初始化新的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")
}
}
}

正如注释中已经提到的,您可能想要采取的路线是在同一WorkoutManager内重新设置状态。无论如何,您都无法将对象分配给@StateObject——由于View的不可变self,您最终会出现编译器错误。

其次,我建议您可能不想依赖WorkoutView中的Button来实现这一点。例如,如果用户通过滑动取消了sheet,则不会调用它。相反,您可以在onChange中侦听sheet的状态(另一种方法是使用sheetonDismiss参数(:

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")
}
}
}

最新更新