Search code examples
objective-cios5screen-orientationscreen-rotation

Screen rotation doesn't work on iOS 5 but is working on iOS 6


I'm currently having a problem with the screen rotation on iOS 5. On iOS 6, everything works fine but the rotation doesn't work on iOS 5 even though the notification UIDeviceOrientationDidChangeNotification is called.

I'm using Storyboard and here's how my ViewController is like:

enter image description here

In order to rotate the screen I use the following methods:

CustomTabBarViewController.mm (UITabBarController)

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    if (isLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
    return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (isLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return (interfaceOrientation == UIInterfaceOrientationMaskAllButUpsideDown);
    }
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

TabBarItemController.mm (UINavigationView)

-(BOOL)shouldAutorotate
{
    return [self.topViewController shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

LoyaltyListController.mm (UIViewController)

- (void) didRotate:(NSNotification *)notification
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight)
    {
        self.navigationController.navigationBarHidden = YES;
        [self hideTabBar:self.tabBarController];
        portraitView.hidden = YES;
        landscapeView.hidden = NO;
    }
    else if (orientation == UIDeviceOrientationPortrait)
    {
        self.navigationController.navigationBarHidden = NO;
        [self showTabBar:self.tabBarController];
        portraitView.hidden = NO;
        landscapeView.hidden = YES;
        [notificationView setFrame:CGRectMake(0, - (notificationView.frame.size.height + 40), notificationView.frame.size.width, notificationView.frame.size.height)];
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
    [(CustomTabBarViewController*)[self tabBarController] setLandscapeOK:YES];
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

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

And here are the screen for iOS 5:

Portrait:

enter image description here

Landscape: (didn't rotate)

enter image description here

Here's what it should look like:

enter image description here

Any idea?


Solution

  • For iOS 5 use - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)

    in iOS 6, its deprecated but it wont matter if you use it. It will only get called in case its iOS 5.0 or below.

    Updated: UIInterfaceOrientationMaskAllButUpsideDown is NOT an UIInterfaceOrientation enum type. Masking is used in iOS 6 to give a mask value to give a combination of orientations you want to support but in iOS 5.

    You will have to check if the interfaceOrientaion is either of

    UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight, UIInterfaceOrientationPortrait or UIInterfaceOrientationPortraightUpsideDown.
    

    and return YES or NO based on which all orientations you want to support.

    In your case Use:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
       return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
     /* If you are supporting all, simply return YES,
    
     if you aren't supporting any return NO, otherwise Use || and check which ones you wanna return YES for.
     In this case you wanna support all except UpsideDown hence use this. */
    }