This is an example visionOS application demonstrating the usage of ScenesManager, a SwiftUI package for managing windows and immersive spaces in visionOS applications.
Created by Tom Krikorian and Tina Debove Nigro
This example app showcases:
- Window management with multiple scenes
- Immersive space integration
- Scene lifecycle tracking
- Event suppression handling
The app demonstrates several key features of ScenesManager:
-
Multiple Window Management
- Main window with content view
- Immersive menu window that appears during immersive experiences
-
Immersive Space Control
- Toggle between normal and immersive modes
- Smooth transitions between states
- State tracking and management
-
Scene Lifecycle Events
- Window opening/closing events
- Immersive space state transitions
- Event suppression demonstration
- visionOS 2.0+
- Swift 5.9+
- Clone this repository:
git clone https://github.com/yourusername/ScenesManager-Example.git-
Open
ScenesManager-Example.xcodeprojin Xcode -
Build and run the project on your visionOS simulator or device
The example app is organized into several key components:
Shows the basic setup of ScenesManager in a visionOS app:
@main
struct ExampleApp: App {
@Environment(\.openWindow) var openWindow
@Environment(\.dismissWindow) var dismissWindow
@Environment(\.openImmersiveSpace) var openImmersiveSpace
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
@State private var scenesManager = ScenesManager()
var body: some Scene {
WindowGroup(id: SceneId.mainWindow.rawValue) {
ContentView()
.environment(\.scenesManager, scenesManager)
.onAppear {
scenesManager.setActions(
openWindow: openWindow,
dismissWindow: dismissWindow,
openImmersiveSpace: openImmersiveSpace,
dismissImmersiveSpace: dismissImmersiveSpace
)
}
}
}
}ContentView: Main window interface with toggle button for immersive spaceImmersiveView: Immersive space content with RealityKit integrationImmersiveMenuView: Controls displayed during immersive experiences
Custom scene identifiers are defined in:
public extension SceneId {
static var mainWindow: Self { .init(rawValue: "MainWindow") }
static var immersiveMenu: Self { .init(rawValue: "ImmersiveMenu") }
}The app includes a button to toggle the immersive space:
struct ToggleImmersiveSpaceButton: View {
@Environment(\.scenesManager) private var scenesManager
var body: some View {
Button {
Task {
await scenesManager.toggleImmersiveSpace()
}
} label: {
Text(scenesManager.immersiveSpaceState == .open ?
"Hide Immersive Space" :
"Show Immersive Space")
}
.disabled(scenesManager.immersiveSpaceState == .inTransition)
}
}Example of window management in the immersive view:
struct ImmersiveMenuView: View {
@Environment(\.scenesManager) private var scenesManager
var body: some View {
VStack {
Text("Second Window!")
}
.padding()
.sceneTracker(for: SceneId.immersiveMenu, onOpen: {
print("Opened")
}, onDismiss: {
onDismiss()
})
}
func onDismiss() {
Task {
await scenesManager.toggleImmersiveSpace()
scenesManager.openWindow(SceneId.mainWindow)
scenesManager.suppressEvents(.openEvent, for: SceneId.immersiveMenu)
}
}
}For more information about the ScenesManager package, visit: