How can I trigger an action when scenePhase
changes in a sheet
? I tried onChange
modifier but it doesn't trigger when the app goes to the background.
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.sheet(isPresented: .constant(true), content: SheetView.init)
}
}
struct SheetView: View {
@Environment (\.scenePhase) private var scenePhase
@State private var isFolderLocked = true
var body: some View {
Text("Hello, world!")
.onAppear {
print("view appeared.")
// if folder is locked, authenticate and unlock it
}
.onChange(of: scenePhase) { newValue in
print("scenePhase changed.")
// if scenePhase == .background, lock folder
}
}
}
Updated code:
import SwiftUI
struct ContentView: View {
@Environment (\.scenePhase) private var scenePhase
var body: some View {
Text("Hello, world!")
.sheet(isPresented: .constant(true)) {
SheetView()
.environment(\.scenePhase, scenePhase)
}
}
}
struct SheetView: View {
@Environment (\.scenePhase) private var scenePhase
var body: some View {
NavigationView {
NavigationLink("Show FirstDetailsView") {
FirstDetailsView()
.environment(\.scenePhase, scenePhase)
}
}
}
}
struct FirstDetailsView: View {
@Environment (\.scenePhase) private var scenePhase
var body: some View {
NavigationLink("Show SecondDetailsView") {
SecondDetailsView()
.environment(\.scenePhase, scenePhase)
}
.onChange(of: scenePhase) { _ in
print("scenePhase changed.")
}
}
}
struct SecondDetailsView: View {
@Environment (\.scenePhase) private var scenePhase
var body: some View {
Text("This is SecondDetailsView")
}
}
CodePudding user response:
The .sheet modifier introduces new presentation and environment is not copied there automatically. We have to do that explicitly, like
struct ContentView: View {
@Environment (\.scenePhase) private var scenePhase
var body: some View {
Text("Hello, world!")
.sheet(isPresented: .constant(true)) {
SheetView()
.environment(\.scenePhase, scenePhase) // << here !!
}
}
}
Tested with Xcode 13.4 / iOS 15.5