3

THIS IS NOT A DUPLICATE QUESTION. A final working solution has NOT been provided yet so please do not close this question until we've accepted an answer or found and provided our own 100% working solution. Thanks!

==================================================================
Using Xcode 4.5.1, we have a tab-bar app with 5 tabs in it. Each tab contains a UINavigationController, so the entire App thus needs to be viewed in Portrait mode. There is one exception: an "image-gallery" type view controller that we need to open and be viewed full-screen, and in LANDSCAPE mode.

We were able to do this easily in iOS5 using the following code in that one particular ViewController:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
   return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

But shouldAutorotateToInterfaceOrientation has been deprecated in iOS6 and doesn't work any more.
So, to get this to work in iOS6, we've taken the following steps so far:
1) created a subclass of the UITabBarController (which is our rootViewController)
2) set its supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation to UIInterfaceOrientationMaskPortrait (But note that we are NOT implementing the shouldAutorotate method in it)
3) Set the PROJECT/Target supported orientations to ALL

This ALMOST works perfectly: our "Image Gallery" ViewController does respond to both landscape modes - as it should - but it still initially opens in Portrait - which is bad. We need it to open up right in Landscape - and not ever be able to be displayed in Portrait. Right now it still doing both.

Any idea why its doing that - or how to fix it?

sirab333
  • 3,662
  • 8
  • 41
  • 54
  • Have you implemented preferredInterfaceOrientationForPresentation? That is one of the new iOS6 methods – rooster117 Nov 01 '12 at 17:19
  • Yes we have. We've tried everything:`preferredInterfaceOrientationForPresentation`, `supportedInterfaceOrientations`, `application:supportedInterfaceOrientationsForWindow` - nothing seems to work. – sirab333 Nov 01 '12 at 18:24
  • How is this not a duplicate of [this question](http://stackoverflow.com/questions/13150154/how-do-i-notify-system-when-supportedinterfaceorientations-changes/)? Because they look identical in concept to me. – KevinH Nov 12 '12 at 16:49

2 Answers2

1

I had this exact same problem with an app I work on and this is how I solved it.

First I created a subclass of UITabBarController called NonRotatingTabBarController with the portrait orientation code

NonRotatingTabBarController.h

#import <UIKit/UIKit.h>

@interface NonRotatingTabBarController : UITabBarController
@end

NonRotatingTabBarController.m

#import "NonRotatingTabBarController.h"

@implementation NonRotatingTabBarController

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

@end

Now when you create your Tab Bar Controller, it needs to be an instance of NonRotatingTabBarController

self.tabBarController = [[NonRotatingTabBarController alloc] init]; // or whatever initialising code you have but make sure it's of type NonRotatingTabBarController

Now in the ONLY view controller which needs to have landscape support, you need to override the rotation methods so it does rotate. In my case, it had to be fixed to landscape

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return (UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight);
}

- (NSUInteger)supportedInterfaceOrientations 
{
    return UIInterfaceOrientationMaskLandscape;
}

In your project/target settings, you MUST have support enabled for all the interface orientations your app uses otherwise it will crash. Let the code above take care of rotation enabling/disabling.

Xcode Project Settings

Hope that helps!

Suhail Patel
  • 13,644
  • 2
  • 44
  • 49
  • Well, you're using a deprecated method: `shouldAutorotateToInterfaceOrientation` - which is no longer supported in iOS6/XCode 4.5.1 - which is exactly why we're having problems in the the first place. If we could still use `shouldAutorotateToInterfaceOrientation` we wouldn't be having any problems :-) I guess I'll still try your code without it, but do you have any fixes for this? – sirab333 Nov 01 '12 at 18:22
  • It is deprecated so it really has no purpose to be in there (i've edited my answer and added `preferredInterfaceOrientationForPresentation` instead) but the main bit which does the job is the `supportedInterfaceOrientations` method – Suhail Patel Nov 01 '12 at 18:34
  • CRASH!: "Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation must return a supported interface orientation!'" I followed your instructions exactly. Question: should the AppDelegate.m have any sort of code in it regarding orientations? Also, the view-controller that needs to be in Landscape - shouldn't that also have the `shouldAutorotate` method implemented in it? – sirab333 Nov 01 '12 at 19:51
  • The shouldAutorotate method is deprecated so not called anymore. Have you set the Supported Interface Orientations as mentioned to ALL the interface orientations used throughout the app? Do you have the `supportedInterfaceOrientations` or `preferredInterfaceOrientationForPresentation` method implemented in your App Delegate (if so, try remove it and see if it works)? – Suhail Patel Nov 01 '12 at 23:40
  • Quick note: `shouldAutorotate` is not deprecated, its a new iOS 6 method -- `shouldAutorotateToInterfaceOrientation` however IS deprecated, as it belongs to iOS 5 (and before.) Now to answer your Q's: YES to #1, and NO to #2. No to #2 cause you can't call those in AppDel. only in ViewControllers. In AppDel you can call `application:supportedInterfaceOrientationsForWindow` - which I am, to support `UIInterfaceOrientationMaskAll`. What's strange is that the only way I don't get a crash is when I take out `supportedInterfaceOrientations` and `preferredInterfaceOrientationForPresentation` from... – sirab333 Nov 02 '12 at 05:26
  • ...the one and only viewController that needs to be in Landscape mode. Its very strange. But when the methods are there the App crashes and when I comment them out the App does NOT crash. AND, when its not crashing, its almost working perfectly, with the only problem being that my Landscape View Controller for some reason also supports Portrait mode (but not Portrait upside down mode.) Weird. Still looking into this. Stay tuned... (and your idea to subclass UITabBarViewController seems to be working perfectly by the way- so thank you for that!) – sirab333 Nov 02 '12 at 05:30
1

shouldAutorotateToInterfaceOrientation method is deprecated in iOS 6

try to implements these following methods.

-(BOOL)shouldAutomaticallyForwardAppearanceMethods{   
     // This method is called to determine whether to 
     // automatically forward appearance-related containment
     //  callbacks to child view controllers.
}
-(BOOL)shouldAutomaticallyForwardRotationMethods{
    // This method is called to determine whether to
    // automatically forward rotation-related containment 
    // callbacks to child view controllers.
}

note : these methods just supported in iOS 6.

Mohammad Rabi
  • 1,412
  • 2
  • 21
  • 41