Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

How to detect UIScreen changes in a UIView subclass?

I'm looking for a reliable way to detect when the UIScreen of a UIView changes.

I'm developing a renderer SDK that provides a custom UIView subclass which performs OpenGL / Metal rendering, driven by a CADisplayLink. To support scenarios like screen mirroring or external displays on iPad, I need to ensure the CADisplayLink is created using the correct UIScreen, so the refresh rate is accurate.

Ideally, I’d like a way to be notified in the view itself (without requiring scene delegate integration) whenever self.window.windowScene.screen changes, even if trait values remain the same.

Any ideas or workarounds that work safely in production would be hugely appreciated!


Since iOS 13, the architecture is:

  • The app can have multiple UIScene instances (typically UIWindowScene).
  • Each UIWindowScene can have multiple UIWindows.
  • Each UIWindow hosts a view hierarchy.

To determine the correct UIScreen, I access self.window.windowScene.screen. If any component in that key path changes (window, windowScene, or screen), I need to detect it and react.

Here’s what I’ve tried so far:

  1. Overriding willMoveToWindow: and didMoveToWindow:
    This allows me to detect changes to window, but if windowScene (of the window) or screen (of the scene) changes directly, I get no notification.

  2. Overriding traitCollectionDidChange:
    This works if the screen change causes a difference in traits (e.g., a different displayScale), but fails if the old and new screens share the same traits (e.g., identical scale).

  3. Listening to UIScene-related notifications
    Notifications like UISceneDidDisconnectNotification or UISceneWillEnterForegroundNotification only indicate scene lifecycle events, not that a particular view or window has moved to a different screen.

  4. Using KVO to observe self.window.windowScene.screen
    I found WebKit does something similar, but in practice this causes crashes. The error message suggests that "windowScene" is not KVO-compliant, and my experience confirms it's not safe in production.

  5. Apple's official guidance uses UIWindowSceneDelegate
    In this example, Apple shows how to update a CADisplayLink in a UIWindowSceneDelegate's windowScene:didUpdateCoordinateSpace:interfaceOrientation:traitCollection:.
    However, as an SDK provider delivering just a UIView, I don't have control over the host app's UIWindowSceneDelegate.

Answered by Frameworks Engineer in 840568022

You probably want to use UIUpdateLink instead of CADisplayLink, which automatically handles screen changes.

You probably want to use UIUpdateLink instead of CADisplayLink, which automatically handles screen changes.

For more inflation about UIUpdateLink, see the documentation here:

How to detect UIScreen changes in a UIView subclass?
 
 
Q