Building for iPhone Duo with SwiftUI

Build adaptive SwiftUI layouts for iPhone Duo using size classes, geometry, safe areas, ReservedRegion, and Split View — with copy-paste code examples.

Last updated

Quick answer

Yes — SwiftUI fully supports iPhone Duo. Apple extends SwiftUI's existing size-class, geometry, and safe-area APIs to Duo rather than introducing a separate framework, and adds one new API, ReservedRegion, for keeping custom UI clear of the fold. Apps that already adapt to size classes work on Duo without changes; apps that don't should adopt NavigationSplitView, adaptive grids, and safe area insets before shipping.

Adaptive Layout

An existing SwiftUI app that already adapts to size classes runs correctly on iPhone Duo with no code changes — Duo adds available space, not a separate SwiftUI framework.

The right mental model is not "does this look right on Duo" but "does this look right at every width my app can be given." The same layout code that handles a resized window on iPad, or Split View on iPhone, is what makes an app work well on Duo.

ArrangementView

Use ArrangementView when two related regions should move together as the window and fold change — not as a replacement for NavigationSplitView.

  • Use it for a player and transcript, a canvas and inspector, or controls over content, with .arrangementViewStyle(.split) or .overlay (the default is .split).
  • Keep list-detail navigation in NavigationSplitView.
  • Skip it when a single column already follows size classes.

Placement rules, axes, and overlay z-index live on the ArrangementView guide.

Size Classes

Branch on horizontalSizeClass and verticalSizeClass, not on the iPhone Duo device model — checking device identity breaks when Apple ships a new posture, a new device, or the user resizes the window in Split View.

SwiftUI exposes those classes through the environment:

AdaptiveView.swift
@Environment(\.horizontalSizeClass)
private var horizontalSizeClass

@Environment(\.verticalSizeClass)
private var verticalSizeClass

var body: some View {
    if horizontalSizeClass == .regular {
        TwoColumnLayout()
    } else {
        SingleColumnLayout()
    }
}

Common mistake

Don't branch on device identity, and don't read screen or device identity from UIScreen.main. Code like if device == .iPhoneDuo { ... } breaks the moment Apple ships a new posture, a new device, or the user resizes the window in Split View. Branch on horizontalSizeClass instead — it reflects the available space, not the hardware. Migration steps: Replace UIScreen.main.

Geometry

Measure the container you were given — with GeometryReader or containerRelativeFrame — when size classes are too coarse, and lay out proportionally rather than against fixed point values.

GeometryExample.swift
GeometryReader { proxy in
    HStack(spacing: 0) {
        SidebarView()
            .frame(width: proxy.size.width * 0.34)
        DetailView()
    }
}

Safe Areas

On Duo, the safe area is asymmetric — the fold consumes space unevenly depending on the pose. Always respect safeAreaInsets rather than assuming symmetric top and bottom padding, and prefer .safeAreaPadding() over manual constants.

ReservedRegion

ReservedRegion is a new API introduced with iOS 27.1 for SwiftUI. It lets custom UI claim the maximum available space while automatically avoiding areas the system reserves for its own chrome — such as controls near the fold. The UIKit equivalent is UIViewReservedRegion. Full usage notes: ReservedRegion.

ReservedRegionExample.swift
ContentView()
    .reservedRegion(.systemControls) { region in
        CustomOverlay()
            .padding(region.insets)
    }

Apple recommendation

Apple recommends adopting ReservedRegion for any custom chrome — toolbars, floating action buttons, or overlays — that would otherwise need to hardcode an inset to avoid the fold.

  • Adopt it for custom chrome that would otherwise need a hardcoded hinge inset. It isn't required for a size-class-only layout.
  • Skip it on system containers — they already avoid reserved areas.
  • Use UIViewReservedRegion for the same job in UIKit.

Use NavigationSplitView for list-detail instead of a manually built master-detail layout — it collapses to one column in Compact width and expands in Regular width as Duo's window resizes.

Split View

Split View on Duo behaves like Split View on iPad: your app can be given any width within a range, and that width can change at any time while the app is running. Test that your layout responds immediately to a live resize, not just to a cold launch at a given width.

Fold Handling

Avoid placing interactive controls or critical content directly across the fold line. Use safe area insets and ReservedRegion to keep tappable elements clear of the hinge, and design your layout so content can flow around it rather than through it.

Multiple Displays

Use the outer display as a secondary scene — preview, now-playing, or summary — while the inner display shows the primary UI; this is multi-scene support, not a UIScreen.main switch.

See the Multiple Displays guide for scene lifecycle details.

Testing

Test every pose in the Duo Simulator: closed, half-open, fully open, and both orientations — layout must update without a relaunch.

See the Xcode testing guide for Device Hub pose controls, and run the compatibility checklist before shipping.

Frequently asked questions

Does SwiftUI support iPhone Duo?

Yes. SwiftUI supports iPhone Duo through its existing size-class, geometry, and safe-area APIs, plus one new API — ReservedRegion — introduced in iOS 27.1 to keep custom UI clear of the fold. An existing SwiftUI app that already adapts to size classes runs correctly on Duo with no code changes.

Do I need to use ReservedRegion?

It isn't required, but Apple recommends it for any custom chrome — toolbars, floating buttons, overlays — that would otherwise need a hardcoded inset to avoid the hinge. The UIKit equivalent is UIViewReservedRegion.

Should I check for the iPhone Duo device model directly?

No. Branch on horizontalSizeClass and verticalSizeClass, not on device identity. Checking the device model breaks the moment Apple ships a new posture, a new device, or the user resizes the window in Split View.