VisionOS app UX/UI for showing hiding the main window

Do you always have to have a main window? Or is there a way to only have a mixed experience?

how would you go about selecting a model from a list and once you select it, I want to hide the list and instead show the model in front of you in an immersive view. Is there a way to re-show the list?

I know that there's the X button at the bottom of the main window, but once you close that, how do you get back to it?

The X button is for closing your App. You can control the hidden logic for your view

Example

Check "The Solar System" scene in the sample project Hello World.

A NavigationStack View will show in default:

Click the "View Outer Space" button to trigger the full immersive mode and then the NavigationStack View is hidden:

The NavigationStack View will return after you click the "Exit the Solar System" button.

How to do?

This can be implemented by the .opacity modifier in SwiftUI. The "Hello World" sample uses the model.isShowingSolar to control the view's hidden state.

// The main navigation element for the app.
NavigationStack(path: $model.navigationPath) {
    TableOfContents()
        .navigationDestination(for: Module.self) { module in
            ModuleDetail(module: module)
                .navigationTitle(module.eyebrow)
        }
}
.opacity(model.isShowingSolar ? 0 : 1)

Try it

Thanks -- this was helpful in zero-ing in on how to hide the main window.

However, one thing I noticed is that this doesn't work if you try to open the immersive experience from .onAppear. Not sure if I'm failing to bind the bool (e.g., model.isShowingSolar) somehow, as I'm new to SwiftUI. Hopefully, this helps someone!

For example:

var body: some View {
    VStack(alignment: .center, spacing: XPPadding.regular) {
        // tapping this button successfully toggles the opacity bool trigger.
        Button("Test") {
            Task {
                await openImmersiveSpace(id: XPSpaceId.exam)
            }
        }
    }
    .onAppear {
        // unfortunately, this did not toggle the opacity bool trigger.
        Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { _ in
            Task {
                await openImmersiveSpace(id: XPSpaceId.exam)
            }
        }
    }
}
VisionOS app UX/UI for showing hiding the main window
 
 
Q