Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger an action when scenePhase changes in a sheet

Tags:

ios

swiftui

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")
    }
}
like image 791
Fawzi Rifai Avatar asked Nov 03 '25 03:11

Fawzi Rifai


1 Answers

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

like image 136
Asperi Avatar answered Nov 04 '25 20:11

Asperi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!