I had a similar issue in my app (Project Graveyard) which has a main volume and utility window to edit content.
I solved this by using some shared state (AppModel) and ScenePhase. What I ended up with was the ability to reopen the main window from the utility window OR open the utility window from the main window.
The first thing to keep in mind is that ScenePhase works differently when used at the app level (some Scene) vs. when using it I a view inside a window, volume, or space. visionOS has a lot of bugs (reported) about the app level uses. I was able to create by solution by using ScenePhase in my views and sharing some state in the AppModel.
Here is a breakdown
Add to AppModel
var mainWindowOpen: Bool = true
var yellowFlowerOpen: Bool = false
The root view of the main window (ContentView in this case)
@Environment(\.scenePhase) private var scenePhase
Then listen for scenePhase using onChange, writing to to the mainWindowOpen bool from appModel.
.onChange(of: scenePhase, initial: true) {
switch scenePhase {
case .inactive, .background:
appModel.mainWindowOpen = false
case .active:
appModel.mainWindowOpen = true
@unknown default:
appModel.mainWindowOpen = false
}
}
We do the same thing in the root view for the other window (or volume)
@Environment(\.scenePhase) private var scenePhase
Then listen to scene phase
.onChange(of: scenePhase, initial: true) {
switch scenePhase {
case .inactive, .background:
appModel.yellowFlowerOpen = false
case .active:
appModel.yellowFlowerOpen = true
@unknown default:
appModel.yellowFlowerOpen = false
}
}
You can download this as an Xcode project if you want to try it our before trying to reproduce it.
https://github.com/radicalappdev/Step-Into-Example-Projects/tree/main/Garden06
There is a also a video available on my website (I really wish we could upload short videos here)
https://stepinto.vision/example-code/how-to-use-scene-phase-to-track-and-manage-window-state/
Topic:
Spatial Computing
SubTopic:
General
Tags: