簡體   English   中英

SwiftUI:如何在父視圖中初始化一個新的 StateObject?

[英]SwiftUI: How to initialize a new StateObject in a parent view?

我有一個類似於以下(簡化)代碼的應用程序架構。 我使用在設置視圖中初始化的WorkoutManager StateObject ,然后通過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最終會出現編譯器錯誤。

其次,我建議您可能不想依賴WorkoutViewButton來執行此操作。 例如,如果用戶通過滑動關閉工作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")
        }

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM