Contents

TN3192: Migrating your iPad app from the deprecated UIRequiresFullScreen key

Support iPad multitasking and dynamic resizing while updating your app to remove the deprecated full-screen compatibility mode.

Overview

Prior to iPadOS 26, apps could request a compatibility mode that opted them out of multitasking and dynamic scene resizing through the UIRequiresFullScreen key. This key-value pair configures iPadOS apps only, and is ignored for iOS apps.

Update apps that rely on UIRequiresFullScreen’s compatibility mode to handle resizing scenes so they can provide a better multitasking experience.

This guide will help you migrate away from UIRequiresFullScreen and handle dynamic resizing. For more information on the enhanced window resizing and improved multitasking, see WWDC25 session 282: Make your UIKit app more flexible.

Determine if your app should update

To support resizable scenes ensure that your app:

If you need to keep UIRequiresFullScreen to support earlier versions of iOS after you’ve made these updates, add UIRequiresFullScreenIgnoredStartingWithVersion to your information property list to specify in which version of iOS you want the system to begin ignoring UIRequiresFullScreen in your app.

For example, if your app is available on iOS 18 and relies on UIRequiresFullScreen to function correctly, add UIRequiresFullScreenIgnoredStartingWithVersion to your Info.plist with a value of 26. Then the system will begin ignoring UIRequiresFullScreen on iOS 26, iPadOS 26 and later, while supporting the full screen behavior on iOS 18, iPadOS or earlier.

With these updates, your app will support resizable scenes and multitasking. To learn more about adopting scene-based life cycle, see TN3187: Migrating to the UIKit scene-based life cycle.

Respond to scene size changes

If your app layout relies on consistent scene size, or uses absolute values for its view geometry, consider using Auto Layout to calculate the size and position of its views through constraints placed on its views.

By using Auto Layout, you’re able to replace static, frame-based layouts in your app with flexible constraint-based layouts that respond to size changes. For more information on Auto Layout, including layout constraints and attributes, see Auto Layout Guide.

When transitioning away from the deprecated UIRequiresFullScreen key, ensure your app’s views adapt to dynamic size changes that occur when users resize windows or change device orientation. Each of these scenarios can cause your app’s scene bounds to change at runtime, potentially breaking layouts that assume fixed dimensions. To learn more about debugging Auto Layout issues, see Unsatisfiable Layouts.

You can adjust your app’s layout when the environment changes, such as when size class, display scale, or layout direction changes occur. To detect these changes, use registerForTraitChanges(_:target:action:) or registerForTraitChanges(_:handler:) to register a list of traits to observe.

To observe a scene’s geometry changing, use windowScene(_:didUpdateEffectiveGeometry:) and compare the coordinateSpace.bounds of both geometries.

Additionally, use isInteractivelyResizing to handle interactive resizing of the scene specifically. For example:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var gameAssetManager = MyGameAssetManager()
    var previousSceneSize = CGSize.zero

    func windowScene(
        _ windowScene: UIWindowScene,
        didUpdateEffectiveGeometry previousGeometry: UIWindowScene.Geometry) {

        let geometry = windowScene.effectiveGeometry
        let sceneSize = geometry.coordinateSpace.bounds.size

        if !geometry.isInteractivelyResizing && sceneSize != previousSceneSize {
            previousSceneSize = sceneSize
            gameAssetManager.updateAssets(sceneSize: sceneSize)
        }
    }
}

In this example, isInteractivelyResizing is queried to only update assets for a new scene size after the interaction finishes. This is helpful for games, where multiple assets may require resizing when the scene changes size or if there are elements of your app’s UI that are computationally expensive to draw.

In SwiftUI, use onInteractiveResizeChange(_:) to adjust how your view behaves when a window is in the process of being resized by the user.

Specify scene sizing preference

To express a preferred minimum size of your scene’s content, use UISceneSizeRestrictions. For example:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    func scene(_ scene: UIScene,
               willConnectTo session: UISceneSession,
               options connectionOptions: UIScene.ConnectionOptions) {

        guard let windowScene = scene as? UIWindowScene else { return }
        windowScene.sizeRestrictions?.minimumSize.width = 500.0
    }
}

The example above specifies a preferred minimum width of 500 points.

In SwiftUI, use the windowResizability(_:) modifier to allow your scene’s content provide sizing information. The value that you specify indicates the strategy the system uses to place minimum restriction on windows that it creates from that scene. For example:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
               .frame(minWidth: 100, maxWidth: 400, minHeight: 100, maxHeight: 400)
        }
        .windowResizability(.contentMinSize)
    }
}

Request scene orientation lock

Some apps may benefit from temporarily locking the orientation. For example, a driving game may want to lock the orientation when the device is expected to rotate for steering a vehicle or a camera apps may need to lock orientation during photo or video capture.

To request orientation lock, override prefersInterfaceOrientationLocked in your view controller subclass. Whenever this preference changes, call setNeedsUpdateOfSupportedInterfaceOrientations(). For example:

class MyRaceViewController: UIViewController {

    override var prefersInterfaceOrientationLocked: Bool {
        return isDriving
    }

    // ...

    var isDriving: Bool = false {
        didSet {
            if isDriving != oldValue {
                setNeedsUpdateOfPrefersInterfaceOrientationLocked()
            }
        }
    }
}

The value returned by prefersInterfaceOrientationLocked indicates to the system that the view controller prefers the scene’s interface orientation to be locked when shown.

If your app uses the camera, use AVCaptureDevice.RotationCoordinator to ensure that captures and camera preview interfaces are correctly oriented regardless of interface orientation lock.

To observe the interface orientation lock, use windowScene(_:didUpdateEffectiveGeometry:) and check if the value of isInterfaceOrientationLocked has changed. For example:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var game = MyGame()

    func windowScene(
        _ windowScene: UIWindowScene,
        didUpdateEffectiveGeometry previousGeometry: UIWindowScene.Geometry) {

        let wasLocked = previousGeometry.isInterfaceOrientationLocked
        let isLocked = windowScene.effectiveGeometry.isInterfaceOrientationLocked

        if wasLocked != isLocked {
            game.pauseIfNeeded(isInterfaceOrientationLocked: isLocked)
        }
    }
}

For more information about locking your scene to your preferred interface orientation and preventing rotation changes, see prefersInterfaceOrientationLocked.

Revision History

  • 2026-02-06 Added information about back deployment support.

  • 2025-09-08 First published.

See Also

Latest