TechnologiesSwiftUIImmersive Spaces and visionOS

MixedImmersionStyle struct

iOSmacOStvOSwatchOSvisionOS✓ renders

An immersion style that displays unbounded content intermixed with other

How it works

MixedImmersionStyle is an immersion style that displays your app's virtual content alongside passthrough video of the person's real surroundings, so the digital scene appears to coexist with the physical room rather than replace it. Reach for it when you open an immersive space but want people to remain aware of and connected to their environment — the default, least-enveloping option on visionOS. You don't construct it directly in most code; instead you refer to it through the ImmersionStyle protocol's mixed value and hand that to the immersionStyle(selection:in:) modifier. Switching to a different conforming style, such as FullImmersionStyle, changes how completely the virtual content occludes the world.

  1. Refer to the style through ImmersionStyle.mixed

    Rather than calling an initializer, you name the style through the ImmersionStyle protocol's static mixed member. In the example the selected style is held in @State private var style: any ImmersionStyle = .mixed, declared as an existential any ImmersionStyle so it can also hold other conforming styles. MixedImmersionStyle is the concrete type that .mixed resolves to.

  2. Store the active style in state you can change

    Because immersion style is a runtime choice, you keep it in mutable state so the view updates when it changes. Here style is @State, and the set closure of the Binding reassigns style = .mixed. Keeping the value in state is what lets a control drive which ImmersionStyle is in effect.

  3. Distinguish styles by their concrete type

    Each immersion style is a distinct type conforming to ImmersionStyle, so you can tell them apart at runtime. The get closure uses String(describing: type(of: style)), which reports "MixedImmersionStyle" when .mixed is active and "FullImmersionStyle" for the full style — the same names used as the tag values on the Picker rows.

  4. Offer the alternatives alongside mixed

    MixedImmersionStyle sits in a family with FullImmersionStyle and ProgressiveImmersionStyle. The Picker lists Text("Mixed") and Text("Full") so the choice between blending content into the room and fully enveloping the person is explicit. In an immersive-space app you would pass the chosen value to the immersionStyle(selection:in:) modifier on your scene.

Try it — Change the set closure from style = .mixed to style = .full so selecting a different segment swaps the active ImmersionStyle, and watch the displayed type name update accordingly.

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.

MixedImmersionStyle.swift
struct MixedImmersionStyleDemo: 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: { String(describing: type(of: style)) },
                set: { _ in style = .mixed }
            )) {
                Text("Mixed").tag("MixedImmersionStyle")
                Text("Full").tag("FullImmersionStyle")
            }
            .pickerStyle(.segmented)
            Text("Mixed blends virtual content with your real surroundings.")
                .font(.caption)
                .foregroundStyle(.secondary)
                .multilineTextAlignment(.center)
        }
        .padding()
    }
}
Live preview
Immersion Style Mixed Full Mixed blends virtual content with your real surroundings.
Immersion Style Mixed Full Mixed blends virtual content with your real surroundings.
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →