3
votes

i am creating a iPad app which supports the ios versions 5 and 6. I have a view controller which is shown at the start of the application only in portrait mode. Later i have a view controller which supports all interface orientations.

I just get it to work on iOS 5 or on iOS 6. Meaning: On iOS 6 the interface orientations supported in a view controller are only working if they are also set in the info.plist file. So i have to set all interface orientations in the info.plist file. It all works on iOS 6 but on iOS 5 it works on startup if the iPad is in Portrait before app start. But if the iPad is in Landscape the app starts in the right way but the notification center is wrong until you perform another rotation manually.

Is there a way to put some other keys in the info.plist file for another iOS version? That's the only solution i can think of. Because if i set only portrait as orientation in the info.plist file it works in iOS 5.

EDIT:

Okay, i explained it a bit confusing. I have get it to work fully in iOS 6 with the methods: shouldAutorotate and supportedInterfaceOrientations:. My Root View Controller just supports Portrait Interface Orientation and in my info.plist i had to select all interface orientations.

The problem:

When i start the App on iOS 5 holding my iPad in Landscape:

The Root View Controller is in Portrait Mode, but the App behaves like it would be in Landscape mode meaning the notification center can be accessed from the side and so on.

My solutions i can think of:

The problem is that i had to set all interface orientations in the info.plist file. That means in iOS 5 the app tries to start in Landscape mode (behavior explained above) even if i just put one possible orientation in the method shouldAutorotateToInterfaceOrientation: .

So there would be 2 solutions: I can make the app rotate in iOS 6 when the specific interface orientation is not selected in the info.plist file or i can "change" the rotation for iOS 5.

Hope you can help me.

3

3 Answers

4
votes

Okay, finally i came up with a solution to it. The Problem was that the Notification Center was accessed the wrong way at startup because of the interface orientations set in the info.plist file.

I have a fullscreen app and didn't get it at first that also the status bar was displayed like in landscape modus while the other views are displayed in portrait modus (rootviewcontroller).

So at application: didFinishLaunchingWithOptions: i put this code:

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

And for all the others who want to have an App with one orientation at startup but to allow several in another sub controller, here the full solution:

Set all interface orientations for iPad in startup.

In my rootViewController have this code:

(Support for old iOS versions)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
}

(Support for new ones)

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotate {
        return NO;
}

In my Sub Controller i have the following:

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}

- (BOOL)shouldAutorotate {
    return YES;
}

Looks simple, but it took me ages to solve the thing with the status bar. If shouldAutorotate doesn't get called you have to use this hack mentioned in other posts.

0
votes

For iOS 6 you need these two overridden methods in your UIViewControllers:

- (NSUInteger)supportedInterfaceOrientations
- (BOOL)shouldAutorotate

Also the Info.plist orientations are just for launch, so they should match your launch orientation which is only Portrait.

Note the auto rotation only works correctly when UIViewcontrollers are used correctly, like for example a stack in UINavigationController. That way when each controller is shown, it will use its specified orientations.

0
votes

here is the method i came up with for backwards compatibility.

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    if ([CMVStaticContainer isPad]) // Custom Method to determine this is on the iPad
    {
        return UIInterfaceOrientationLandscapeRight;
    }
    else
    {       
        return UIInterfaceOrientationPortrait;
    }
}

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAll;
}

- (BOOL)shouldAutorotate{
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    if (orientation == UIDeviceOrientationUnknown) return YES;
    BOOL result = [self shouldAutorotateToInterfaceOrientation:orientation];
    return result;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    // Return YES for supported orientations
    if ([CMVStaticContainer isPad]) // Custom Method to determine this is on the iPad
    {
        return interfaceOrientation == UIInterfaceOrientationLandscapeRight;
    }
    else
    {       
        return YES;
    }

}

I determined that for UIDeviceOrientationUnknown you should always return yes. then my code forwards it onto the other orientation code from iOS 5

Oh, I also encountered an issue with "Standard Classes" as the rootViewController because that is the one getting the message, I believe i subclassed it and determined the view controller that was on top and send the message through it to ensure the view controller on top would determine the preferred orientation as well as the shouldAutorotate commands.

This code does not include that, but that is because I went to using Modal Presentation for new view controllers as opposed to UINavigationController for my root. but that was an unrelated decision.