TechnologiesSwiftUIImmersive Spaces and visionOS

ProgressiveImmersionStyle struct

iOSmacOStvOSwatchOSvisionOS✓ renders

An immersion style that displays unbounded content that partially replaces

How it works

ProgressiveImmersionStyle is one of the built-in immersion styles you apply to an ImmersiveSpace in visionOS to control how much of the wearer's real surroundings your content replaces. Unlike a fully immersive style, it renders your scene within a bounded portal that the person can dial open and closed using the Digital Crown, blending virtual content with the passthrough view of their actual room. Reach for it when you want an immersive experience that the wearer can ease into and stay grounded in, rather than one that takes over their view all at once. You rarely name the type directly; instead you refer to its static accessor and hand it to the immersion-style modifier.

  1. Refer to the style through the .progressive accessor

    ProgressiveImmersionStyle is surfaced as the static property progressive on ImmersionStyle, so you write .progressive rather than constructing the struct yourself. In the example the state's initial value is set with @State private var style: any ImmersionStyle = .progressive, which resolves to a ProgressiveImmersionStyle instance.

  2. Store the active style behind an ImmersionStyle binding

    Because immersion is selectable at runtime, you keep the current style in state typed as the existential any ImmersionStyle. The style property here holds .progressive, and because it is @State, reassigning it later lets the system animate between styles.

  3. Apply it with immersionStyle(selection:in:)

    The immersionStyle modifier is what actually installs the style on the surrounding scene. It takes a binding for the live selection and a list of the styles you permit. In the example .immersionStyle(selection: $style, in: .progressive) passes $style as the selection and lists .progressive as the allowed style.

  4. Choose a portal aperture (optional)

    ProgressiveImmersionStyle can be parameterized with the fraction of the field of view it occupies via its initializer, for example ProgressiveImmersionStyle(immersion:) bounded by an aspect that the Digital Crown then adjusts within. The example uses the bare .progressive, which adopts the system's default aperture range.

Try it — Change .immersionStyle(selection: $style, in: .progressive) to .immersionStyle(selection: $style, in: .full) and watch the surroundings be replaced entirely instead of gradually through a crown-adjustable portal.

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.

ProgressiveImmersionStyle.swift
struct ProgressiveImmersionStyleDemo: View {
    @State private var style: any ImmersionStyle = .progressive

    var body: some View {
        VStack(spacing: 12) {
            Image(systemName: "visionpro")
                .font(.largeTitle)
            Text("Progressive Immersion")
                .font(.headline)
            Text("Gradually replaces the user's surroundings.")
                .font(.caption)
                .multilineTextAlignment(.center)
                .foregroundStyle(.secondary)
        }
        .padding()
        .immersionStyle(selection: $style, in: .progressive)
    }
}
Live preview
Progressive Immersion Gradually replaces the user's surroundings.
Progressive Immersion Gradually replaces the user's surroundings.
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →