8

I always used UIScreen.main.bounds.size to get the screen size on iOS and worked fine.

Now (in iOS 16, I believe) when I try to access the screen size with the "main" instance of UIScreen a warning is displayed:

"main' will be deprecated in a future version of iOS: Use a UIScreen instance found through context instead: i.e, view.window.windowScene.screen

So my question is: What is the correct way to get the screen size? for simplicity let's imagine we are on the iPhone with, consequently, only one screen available. Thank you

Luca
  • 1,704
  • 3
  • 29
  • 42
  • 1
    This article might be helpful: https://designcode.io/swiftui-handbook-detect-screen-size – wzso Jul 20 '23 at 23:23

3 Answers3

2

Per Apple discussion on UIScreen.main deprecation:

Apple discourages the use of this symbol. Use a UIScreen instance found through context instead. For example, reference the screen that displays a view through the screen property on the window scene managing the window containing the view.

Here is an extension to find the UIScreen instance through context:

extension UIViewController {
  func screen() -> UIScreen? {
    var parent = self.parent
    var lastParent = parent
    
    while parent != nil {
      lastParent = parent
      parent = parent!.parent
    }
    
    return lastParent?.view.window?.windowScene?.screen
  }
}

For reference, this is the same UIScreen instance associated with the windowScene in the SceneDelegate:

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

    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
    
    let screen = windowScene.screen
    
    configureNavigationBar()
  }
vmanjz
  • 1,156
  • 1
  • 10
  • 23
1

From a ViewController:

let screenSize = self.view.window?.windowScene?.screen.bounds.size
ZGski
  • 2,398
  • 1
  • 21
  • 34
J. Coder
  • 31
  • 6
  • 1
    So this is a solution only if you still use the old ViewController lifecycle? Thanks! – Luca Nov 17 '22 at 07:52
1
extension UIWindow {
    static var current: UIWindow? {
        for scene in UIApplication.shared.connectedScenes {
            guard let windowScene = scene as? UIWindowScene else { continue }
            for window in windowScene.windows {
                if window.isKeyWindow { return window }
            }
        }
        return nil
    }
}


extension UIScreen {
    static var current: UIScreen? {
        UIWindow.current?.screen
    }
}

This way, you can use this anywhere, just like you could with the UIScreen.main.

usage

UIScreen.current?.bounds.size
eastriver lee
  • 173
  • 2
  • 9