Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPad Device orientation using statusBarOrientation

(Xcode 6, Swift, iOS8)

I am trying to find the device orientation for iPad, and it seems to be needlessly complicated. where am I going wrong?

At first, I tried to use the interfaceOrientation of my UIViewController, but it is unreliable and deprecated. Apple recommend using the statusBarOrientation property. (1)

statusBarOrientation is of type UIApplication. I tried to create an instance like so:

var o: UIApplication

and then test:

if (o.statusBarOrientation.isLandscape) { ... }

but received error

Variable 'o' used before being initialized.

Which makes no sense to me at all. Why would I initialize it to a value? I would overwrite the value that I want!?

Then I tried simply creating a variable as recommended in the docs:

var statusBarOrientation: UIInterfaceOrientation

but on a trace:

statusBarOrientation = (UIKit.UIInterfaceOrientation) (0xa0)

So I tried to subclass UIApplication, and access the property through my subclass.

From here, more complexity. It appears that "Every app must have exactly one instance of UIApplication (or a subclass of UIApplication)." (2)

This led me to the following post, which seems to create a Main routine in Swift?!
Subclass UIApplication with Swift

Again, my goal is to grab the current device orientation, and test it in a conditional. Pseudocoded:

var o = (get device orientation)
if (o == portrait ) { ... } else { ... }

As you can see, I'm in the weeds... any help would be greatly appreciated.

EDIT: I did manage to get it sort-of working with the following:

var o = UIApplication.sharedApplication().statusBarOrientation;
if (o.isLandscape) { ...

however, on initial load, when the device is rotated to landscape, o.isLandscape is being reported as false.

  1. Search documentation for "UIViewController," and look in the "Configuring the View Rotation Settings." Under Discussion, "Do not use this property for informing layout decisions. Instead, use the statusBarOrientation property, described in UIApplication Class Reference."

  2. Search documentation for "UIApplication" and look under Subclassing notes

like image 552
kmiklas Avatar asked Jun 19 '14 17:06

kmiklas


2 Answers

There appear to be a couple of things wrong here that I'll try to clear up. First of all, the following doesn't create an instance of UIApplication, merely a variable of that type:

var o: UIApplication

If you want to create an instance of UIApplication, you should be doing this:

let o: UIApplication = UIApplication()

But, as you discovered, this won't work for UIApplication; you shouldn't be creating additional instances of UIApplication. Instead, you should be accessing the singleton instance, sharedApplication():

let o: UIApplication = UIApplication.sharedApplication()

Note: You had the same issue with your orientation variable as you did with the app delegate variable. The following line doesn't say what value to put into variable statusBarOrientation; it is not initialized:

var statusBarOrientation: UIInterfaceOrientation

Any one of these lines does what you intended:

var statusBarOrientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
var o: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
let orientation = UIApplication.sharedApplication().statusBarOrientation

Anyway, when you put it all together, you can get the current status bar orientation with the following.

if let theAppDelegate = UIApplication.sharedApplication() {
    let orientation = theAppDelegate.statusBarOrientation

    if orientation.isPortrait {
        // Portrait
    } else {
        // Landscape
    }
}

ALSO

You need to specify that your app can support the landscape orientations. This can either be done via the orientation check boxes in the application summary, or programmatically through the view controller's supported orientations method (you can find plenty on this online).

like image 134
Mick MacCallum Avatar answered Sep 27 '22 21:09

Mick MacCallum


This works with Xcode 6.1 to avoid the "Bound value in a conditional binding must be of Optional type UIApplication" error that occurs with the use of an if let statement.

let orientation = UIApplication.sharedApplication().statusBarOrientation

    if orientation.isPortrait {
        // Portrait
    } else {
        // Landscape
    }
like image 27
amurray4 Avatar answered Sep 27 '22 21:09

amurray4