Apple’s guidance is explicit: the inner display does not honor supported interface orientations.
Why it happens
Orientation locking was always a way of saying “only ever lay out at one aspect ratio”. That worked when a phone had one screen and a hinge did not exist. On iPhone Duo the user physically unfolds the device, and the app is expected to occupy the space that results. Refusing to rotate is not a meaningful answer to that, so the inner display ignores the request.
If your entire layout strategy rests on the guarantee that width is always less than height, that guarantee is gone.
There is one exception, and it is not an escape route. An app that still carries UIRequiresFullScreen does have its supported orientations respected — but Apple is equally clear that such an app scales on the inner display, including in Split View, and still resizes when the device opens and closes. You trade a layout problem for a scaled app. See launch screen and resizability.
The fix
Replace orientation checks with size classes, which describe the space you actually have:
// Before
if UIDevice.current.orientation.isLandscape { … }
// After — SwiftUI
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
var body: some View {
if horizontalSizeClass == .regular {
WideLayout()
} else {
NarrowLayout()
}
}
// After — UIKit
switch traitCollection.horizontalSizeClass {
case .regular: applyWideLayout()
default: applyNarrowLayout()
}
The size classes to design against are:
- Inner display — regular width × regular height in either orientation, with room for a sidebar
- Outer display, portrait — compact width × regular height, familiar iPhone territory
- Outer display, landscape — compact in both dimensions, the tightest space on the device
Note that Split View multitasking changes your size class too, without any change in orientation. Size classes handle both cases with one code path; orientation handles neither.
Cross-platform stacks need the same change. Android reached the same conclusion independently: from API level 36, it ignores screenOrientation, resizeableActivity and the aspect-ratio limits on any display 600dp wide or more, and the opt-out disappears at API 37 — see the foldable era. In React Native, replace a cached Dimensions.get('window') with the useWindowDimensions() hook so the component re-renders on resize. In Flutter, read MediaQuery.sizeOf(context) in build rather than caching it in initState.
Games: a lock is allowed, a fixed screen is not
Apple’s Human Interface Guidelines give games more room: a game may lock to portrait or to landscape. It still has to fill the screen as the device pose changes. While resizing, keep text and control sizes as consistent as possible, and prefer changing the aspect ratio over letterboxing or pillarboxing. If bars are unavoidable, put artwork in the padding so the game still feels full screen.
How to verify
Set the app to portrait-only in the target settings, then run it on the Duo inner display and rotate. The app will rotate regardless. Every layout it produces should be one you designed on purpose.