Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'statusBarOrientation' was deprecated in iOS 13.0 when attempting to get app orientation

Tags:

ios

swift

ios13

Simple put, I was relying on the following code to provide the orientation of the application. This is utilized for several reasons within the application:

  • Per UX specification, the layout of the stackview is set based upon orientation for iPad (horizontal when in landscape, vertical when in portrait)
  • Building on the previous item, the stackview is placed on the screen to the left (portrait) or on the top (landscape)
  • There is custom rotation logic that responds differently based on the status. tl;dr is that on an iPad, the app presents itself with significant differences between orientation

I am just tasked with maintenance in this scenario and do not have the ability to make significant changes that deviate from the current (and properly functioning) layout logic in place.

As of now, it relies upon the following to capture application orientation:

var isLandscape: Bool {
    return UIApplication.shared.statusBarOrientation.isLandscape
}

However, with the Xcode 11 GM version, I am given the following deprecation warning:

'statusBarOrientation' was deprecated in iOS 13.0: Use the interfaceOrientation property of the window scene instead.

How can I go about getting the orientation of the application via status bar?

like image 844
CodeBender Avatar asked Sep 16 '19 23:09

CodeBender


5 Answers

Swift 5, iPadOS 13, taking the multi-window environment into account:

if let interfaceOrientation = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.windowScene?.interfaceOrientation {
 // Use interfaceOrientation
}
like image 88
Adam Avatar answered Nov 14 '22 10:11

Adam


Swift 5, iOS 13, but compatible with older versions of iOS:

extension UIWindow {
    static var isLandscape: Bool {
        if #available(iOS 13.0, *) {
            return UIApplication.shared.windows
                .first?
                .windowScene?
                .interfaceOrientation
                .isLandscape ?? false
        } else {
            return UIApplication.shared.statusBarOrientation.isLandscape
        }
    }
}

Usage:

if (UIWindow.isLandscape) {
    print("Landscape")
} else {
    print("Portrait")
}
like image 28
Sasho Avatar answered Nov 14 '22 12:11

Sasho


This is how I do it for iOS13 for Swift 5.1:

var statusBarOrientation: UIInterfaceOrientation? {
    get {
        guard let orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation else {
            #if DEBUG
            fatalError("Could not obtain UIInterfaceOrientation from a valid windowScene")
            #else
            return nil
            #endif
        }
        return orientation
    }
}
like image 18
Geoff H Avatar answered Nov 14 '22 10:11

Geoff H


Objective C, iOS 13 and compatible with older versions:

+ (BOOL)isLandscape
{
    if (@available(iOS 13.0, *)) {
        UIWindow *firstWindow = [[[UIApplication sharedApplication] windows] firstObject];
        if (firstWindow == nil) { return NO; }

        UIWindowScene *windowScene = firstWindow.windowScene;
        if (windowScene == nil){ return NO; }

        return UIInterfaceOrientationIsLandscape(windowScene.interfaceOrientation);
    } else {
        return (UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation));
    }
}

I added this to a UIWindow Category.

like image 9
banana1 Avatar answered Nov 14 '22 12:11

banana1


I came up with the following solution, but am open to improvements or suggestions should I be making some mistake I am not aware of:

var isLandscape: Bool {
    return UIApplication.shared.windows
        .first?
        .windowScene?
        .interfaceOrientation
        .isLandscape ?? false
}
like image 8
CodeBender Avatar answered Nov 14 '22 11:11

CodeBender