[英]SwiftUI: How to initialize a new StateObject in a parent view?
I have an app architecture similar to the below (simplified) code.我有一个类似于以下(简化)代码的应用程序架构。 I use a
WorkoutManager
StateObject
which I initialize in the set up view, then pass down to its children via EnvironmentObject
.我使用在设置视图中初始化的
WorkoutManager
StateObject
,然后通过EnvironmentObject
传递给它的子项。 The problem is that upon dismissing the .sheet
there isn't any life cycle event which initializes a new WorkoutManager
, which I need in order to be able to start new workouts consecutively.问题是,在解除
.sheet
,没有任何生命周期事件会初始化一个新的WorkoutManager
,我需要它才能连续开始新的锻炼。 How in this example below can I give WorkoutView
the ability to reinitialize WorkoutManager so that it is a clean object?在下面的这个例子中,我如何让
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")
}
}
}
As mentioned in the comments already, the route you probably want to take is reseting the state within the same WorkoutManager
.正如评论中已经提到的,您可能想要采取的路线是在同一个
WorkoutManager
状态。 You wouldn't be able to assign a new object to a @StateObject
anyway -- you'll end up with compiler errors because of the View
's immutable self
.无论如何,您都无法将新对象分配给
@StateObject
- 由于View
的不可变self
最终会出现编译器错误。
Secondly, I'd suggest that you probably don't want to rely on the Button
in your WorkoutView
to do this.其次,我建议您可能不想依赖
WorkoutView
的Button
来执行此操作。 For example, if the user dismissed the sheet
by swiping, that wouldn't get called.例如,如果用户通过滑动关闭工作
sheet
,则不会调用。 Instead, you could listen for the sheet
's state in onChange
(another method would be using the onDismiss
parameter of sheet
):相反,您可以在
onChange
监听sheet
的状态(另一种方法是使用sheet
的onDismiss
参数):
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")
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.