How it works
ImmersionStyle is the protocol that describes how much of a person's surroundings an immersive space replaces on visionOS. An immersive space can blend its content with the real world, gradually expand to fill the view, or take over the wearer's surroundings entirely, and a value conforming to ImmersionStyle is what selects between those behaviors. Reach for it when you present an immersive space and need to control, or let the person change, how immersive that space feels.
Hold a style as
any ImmersionStyleBecause
ImmersionStyleis a protocol with several concrete conformers, you store a chosen style behind the existential typeany ImmersionStyle. In the example the current style lives in@State private var style: any ImmersionStyle, so the value can be swapped between different conforming styles while the view reacts to the change.Choose a built-in style with the static factories
SwiftUI ships standard conformers exposed as static members, so you rarely write a custom type. The code assigns
.mixedto keep passthrough visible,.progressiveto expand the space as the person engages, and.fullto replace their surroundings — each one a concreteImmersionStylevalue selected through dot syntax.Swap styles at runtime
Since the style is just a value, you can change which
ImmersionStyleis active in response to input. Theupdate(_:)method does exactly this, switchingstylebetween.progressive,.full, and.mixedso the level of immersion follows the person's choice rather than being fixed at launch.Recognize the automatic style
When you don't specify a style, the system supplies a default whose concrete type is
AutomaticImmersionStyle. The example checksstyle is AutomaticImmersionStyle, illustrating that a storedany ImmersionStylecan be inspected to discover which conforming style is currently in effect.Apply the style to an immersive space
An
ImmersionStylevalue is meant to be handed to an immersive space via theimmersionStyle(selection:in:)scene modifier, which binds the chosen style to the space and limits which styles it may adopt. Thestylestate here is the value you would pass to that modifier; the surroundingPickerandVStacksimply give the wearer a way to pick which style is selected.
default branch in update(_:) from style = .mixed to style = .full so an unrecognized selection produces a fully immersive space instead of passthrough.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct ImmersionStyleDemo: View {
@State private var style: any ImmersionStyle = .mixed
var body: some View {
VStack(spacing: 16) {
Text("Immersion Style")
.font(.headline)
Picker("Style", selection: Binding(
get: { label },
set: { update($0) }
)) {
Text("Mixed").tag("Mixed")
Text("Progressive").tag("Progressive")
Text("Full").tag("Full")
}
.pickerStyle(.segmented)
Text("Selected: \(label)")
.foregroundStyle(.secondary)
}
.padding()
}
private var label: String {
if style is AutomaticImmersionStyle { return "Mixed" }
return "Mixed"
}
private func update(_ name: String) {
switch name {
case "Progressive": style = .progressive
case "Full": style = .full
default: style = .mixed
}
}
}