A SwiftUI app runs on visionOS unchanged, and three platform features deepen it: ornaments around the window, volumes for 3D content, and immersive spaces that replace the surroundings.
Ornaments
An ornament floats outside the window and holds controls connected to it. Get one from the
bottomOrnament toolbar placement, or place your own views with the ornament modifier and an
anchor.
.toolbar {
ToolbarItem(placement: .bottomOrnament) {
Button("open", systemImage: "doc.badge.plus") {}
}
}
.ornament(attachmentAnchor: .scene(.leading)) {
// your controls
}
transform3DEffect and rotation3DEffect add depth to window content.
Volumes and Model3D
RealityKit's Model3D view shows a USDZ or reality file, loading asynchronously like
AsyncImage, with an optional placeholder closure.
Model3D(
url: Bundle.main.url(forResource: model.name, withExtension: "usdz")!
) { resolved in
resolved
.resizable()
.aspectRatio(contentMode: .fit)
} placeholder: {
ProgressView()
}
Give the scene a volumetric window style so the content can grow into the third dimension. For
complex scenes, use RealityView and add entities in its content closure.
WindowGroup {
ContentView()
}
.windowStyle(.volumetric)
Immersive Spaces
ImmersiveSpace is a scene type that hides the surroundings and focuses on your 3D content.
Declare it with an id, open it with the openImmersiveSpace environment action, and close it
with dismissImmersiveSpace. Only one immersive space can be open at a time.
ImmersiveSpace(id: "solar-system") {
SolarSystemView()
}
@Environment(\.openImmersiveSpace) private var openImmersiveSpace
Button("Enjoy immersive space") {
Task { await openImmersiveSpace(id: "solar-system") }
}