Status bar is Landscape, but [[UIApplication sharedApplication] statusBarOrientation] returns portrait
Asked Answered
F

5

19

This problem appears to be intermittent, but I am not sure why exactly. When running my application on the device (iPad), I have some code to load a scroll view with some image views according to the current device orientation. Even though the device is landscape before loading, the views are being loaded as if it were portrait.

The orientation is found by calling [[UIApplication sharedApplication] statusBarOrientation].

The views are set up to adjust their positions when the device is rotated, and indeed, rotating to portrait and then back to landscape returns them to the correct landscape positions. Is it the case that all applications start off in portrait and soon change to landscape if required? Am I trying to check the orientation too soon (during the init of the first view controller to be loaded)?

Feudatory answered 27/4, 2011 at 20:49 Comment(3)
Hi, have found a solution to get the correct orientation info when makeKeyAndVisible is called a bit later than your code? Myself I've also tried self.interfaceOrientation to no avail.Minsk
@delirus It was a while ago now, but I believe the problem was that I was creating my own currentOrientation property to store the interface orientation of my UIViewController subclass, and then using the code above to find its value. Changing to self.interfaceOrientation worked for me. If you're still having trouble, try calling makeKeyAndVisible at the start of your app delegate's didFinishLaunchingWithOptions: method and see if it makes a difference.Feudatory
thanks for reply. Already tried to call makeKeyAndVisible earlier, but it turned out my controller's viewDidLoad and awakeFromNib are always called before delegate's didFinishLaunchingWithOptions:. Anyway, I won't give up :)Minsk
F
7

If you're subclassing UIWindow or the status bar you'll see this because that's the ipad device's native orientation. The UIWindow translates the orientation and coordinates into what we're used to. After you makeAndKeyVisible, your device and interface orientation in view controllers should be as expected. You wouldn't by chance be using MTStatusBarOverlay would you? I went through the same thing and it came down to the order of instatiation.

Felicio answered 3/5, 2011 at 4:7 Comment(4)
This is interesting - I'm not subclassing UIWindow, it is a UIViewController subclass that requests the orientation. However, this view controller subclass is instantiated prior to the window calling makeKeyAndVisible. I suppose this means that I will need to move the request for statusBarOrientation out of the init method. Should the controller's viewDidLoad be called after the window is made key and visible? I still haven't figured out why the problem is intermittent though.Feudatory
You shouldn't need to call viewDidLoad yourself, it gets called automatically once the view is actually instantiated. If you put that statusBarOrientation in viewDidLoad it should be good to go.Felicio
You might also have better luck looking at the interfaceOrientation property of your own UIViewController.Felicio
Yes, sorry - I didn't mean to imply that I was calling viewDidLoad myself, just wondering at what point the application calls it exactly. Hmmm - now you mention the UIViewController's interfaceOrientation property, I can't think why on earth I wasn't using it already... I was creating my own currentOrientation property and tracking status bar orientation and changes in rotation. I think that will make a big difference. Thanks for your suggestions, I think I'm on the right track now.Feudatory
H
35

OK Fixed.

Using UINavigationController, when I popToViewController:animated: from a landscape view to a portrait view, the destination view appears correct but the status bar and also the UIKeyboard keeps the landscape configuration, making a real mess.

Working around After thousands of recommendations about statusBarOrientation and references read... https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-6_0/index.html

"The setStatusBarOrientation:animated: method is not deprecated outright. It now works only if the supportedInterfaceOrientations method of the top-most full-screen view controller returns 0. This makes the caller responsible for ensuring that the status bar orientation is consistent." (thanks to Vytis in here)

statusBarOrientation only works if supportedInterfaceOrientations returns 0, so... that give us a guess.

If statusBarOrientation is not as expected, one zero return will do it (if always return 0, the view wont rotate, so:

// if deviceOrientation is A (so I expect statusbarOrientation A
// but statusbarOrientation is B
// return 0
// otherwise 
// return user interface orientation for A

- (NSUInteger)supportedInterfaceOrientations {
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
    UIInterfaceOrientation statusBarOrientation =[UIApplication sharedApplication].statusBarOrientation;
    if(deviceOrientation == UIDeviceOrientationPortrait || deviceOrientation == UIDeviceOrientationPortraitUpsideDown){
        if(statusBarOrientation != UIInterfaceOrientationPortrait ||statusBarOrientation != UIInterfaceOrientationPortraitUpsideDown){
             return 0;
        }
    }
    // otherwise
    return UIInterfaceOrientationMaskPortrait;
}

Now, in viewDidAppear (believe me, I use this call even when the keyboard notification is recived:

[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;

more than 48 labor hrs in this. Hope this helps a while, thanks to all.

Haircloth answered 25/1, 2013 at 20:47 Comment(6)
SubstanceMX, your second if statement is always true. You should have put && instead of || there.Calorifacient
Since I wrote this, to this day, apple has been hacked, moved files, updated ios and I think something of that made the link went broken.Haircloth
As I remember, the second statement (statusBarOrientation != UIInterfaceOrientationPortrait ||statusBarOrientation != UIInterfaceOrientationPortraitUpsideDown) Is what helps to check if statusBar gives us a clue about the orientation beyond the value of the device orientation. At my point of view, they are not updated properly.Haircloth
You, my friend, deserve a medal ! +1Clapboard
Thank you. In my case, just return 0 and set statusBar orientation.Scalar
Thanks for your hard work, I'm sure this wasn't easy to resolve, but much appreciated !!Cockatiel
F
7

If you're subclassing UIWindow or the status bar you'll see this because that's the ipad device's native orientation. The UIWindow translates the orientation and coordinates into what we're used to. After you makeAndKeyVisible, your device and interface orientation in view controllers should be as expected. You wouldn't by chance be using MTStatusBarOverlay would you? I went through the same thing and it came down to the order of instatiation.

Felicio answered 3/5, 2011 at 4:7 Comment(4)
This is interesting - I'm not subclassing UIWindow, it is a UIViewController subclass that requests the orientation. However, this view controller subclass is instantiated prior to the window calling makeKeyAndVisible. I suppose this means that I will need to move the request for statusBarOrientation out of the init method. Should the controller's viewDidLoad be called after the window is made key and visible? I still haven't figured out why the problem is intermittent though.Feudatory
You shouldn't need to call viewDidLoad yourself, it gets called automatically once the view is actually instantiated. If you put that statusBarOrientation in viewDidLoad it should be good to go.Felicio
You might also have better luck looking at the interfaceOrientation property of your own UIViewController.Felicio
Yes, sorry - I didn't mean to imply that I was calling viewDidLoad myself, just wondering at what point the application calls it exactly. Hmmm - now you mention the UIViewController's interfaceOrientation property, I can't think why on earth I wasn't using it already... I was creating my own currentOrientation property and tracking status bar orientation and changes in rotation. I think that will make a big difference. Thanks for your suggestions, I think I'm on the right track now.Feudatory
S
4

Just in case somebody else runs into this, I see a lot of apps that have similar issues in iOS5, actually on iPhone.

It might be a bug in iOS 5 or just an interference with a common behavior...

I use a custom root view controller class (a UITabBarController subclass, no idea whether that matters) and in that class I've overridden "shouldAutorotateToInterfaceOrientation" to only start rotating after my initial screen setup is done (doing otherwise messed some things up).

What I do now is I re-use this class to also set the statusBarOrientation manually to portrait before I allow rotations and to whatever the UI rotates to afterwards.

[[UIApplication sharedApplication] setStatusBarOrientation:toInterfaceOrientation animated:YES];

I believe this could fix THIS issue, too, even if the cause might be unrelated.

Swipple answered 16/8, 2011 at 0:12 Comment(2)
This is brilliant. This is a nice way to mask the "wrong notifications" we get. I may link to your response in my question, thxHartmann
thanks i used your approach to update my rotation variable in -willrotate delegate method like this:orientation= toInterfaceOrientation;Scribble
C
1

If you are having this issue at launch time, you need to use UIDevice to get the device orientation, since statusBarOrientation will always be portrait until after application:didFinishLaunchingWithOptions:. The only caveat is that you need to enable device orientation notifications prior or asking UIDevice for the orientation.

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
Crabtree answered 20/3, 2013 at 20:4 Comment(0)
O
0

Did you make sure you have all these in info.plist ?

<key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
Orabelle answered 3/5, 2011 at 1:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.