Skip to content
iPhone Duo SupportGet help

Stop using UIScreen.main — read the screen from the window scene

Blockerlayout

What you see

Wrong scale factor, wrong bounds, or blurry rendering when the app is on the outer display or after moving between displays.

Apple stated in Prepare your app for iPhone Duo that references to the main screen will be deprecated, and that apps should avoid them on two-display devices.

Why it happens

UIScreen.main returns a single global screen. iPhone Duo has two: a 7.6-inch inner display at 430 ppi and a 5.4-inch outer display at 460 ppi. The two have different sizes and different pixel densities, and your app can move between them while running — when the user folds the device closed, the app can continue on the cover display.

A global “main screen” cannot answer “which display is this view actually on?”, so any value read from it is unreliable on this device.

The fix

Scale is a trait. Read it from the trait collection, which updates automatically when the view moves between displays:

// Before
let scale = UIScreen.main.scale

// After
let scale = traitCollection.displayScale

When you need the screen object itself, reach it through the window scene that actually contains your view:

// Before
let bounds = UIScreen.main.bounds

// After
let screen = view.window?.windowScene?.screen

For layout, prefer not to touch the screen at all. view.bounds, the safe area insets, and size classes describe the space your app has been given, which is what layout actually depends on — and in Split View multitasking that space is smaller than the display regardless.

In SwiftUI, GeometryReader and the size-class environment values cover nearly every case without a screen reference.

How to verify

Launch the app on the inner display, then close the device so it continues on the outer display. Log traitCollection.displayScale and your computed sizes across the transition; the values should track the display the app is currently on.

← All checksGet help with this