I want to return to the main screen of my SwiftUI watchOS app whenever the app goes from "not shown" to "shown", but I am having difficulty accomplishing this for the case when I cover my watch to close/hide my app.
Background: I use sheets to show the views because I'm not using a list/detail pattern, and send the binding for each sheet to the sheet's view, and then the sheet's view has code like:
.onChange(of: scenePhase) { phase in
if (phase != .active) { isShowing = false }
}
At some point, I'll need to deal with what happens with always-on mode, but that's not my concern right now -- first I'm having trouble with what happens if the app is showing a non-root view and I cover the watch with my hand to go back to the watch face, then tap the complication to return to the app. It returns to that non-root view.
I put in some diagnostic prints on a switch(phase) in the .onChange() and it looks like the app isn't notified about this type of event, and when I tap my complication/widget to re-open the app, it also doesn't trigger a change of scenePhase (my last print from before I covered the watch just says "PHASE ACTIVE", and there's not a new print to the console when I restart the app afterwards).
If I cover the app with my hand to close it, I'd really like to be able to return to the root view when I "restart" the app.
Thanks in advance for any insight!
I have found a solution.
Apparently using @Environment(\.scenePhase) var scenePhase
in the modal sheet's view does not work by itself. The scenePhase
inside the sheet's view just seems to stay equal to .active
even if the app is closed (by, for example, covering the watch with your hand).
However, I found a solution at https://stackoverflow.com/questions/72620039/trigger-an-action-when-scenephase-changes-in-a-sheet
If I "send" the scenePhase
value that the root view pulls from the environment explicitly to the sheet view or one of its ancestors using the modifier .environment(\.scenePhase, scenePhase)
, then the @Environment(\.scenePhase) var scenePhase
in the sheet view gets the actual current phase and can monitor its changes. It also works to send it as a parameter to the sheet's view. However, since I want to access it in multiple sheets opened from yet another sheet, putting it back into the environment for the full child view hierarchy seemed more appropriate.