Reputation: 2819
I have been scouring the internet for a solution to this but am finding nothing. I am trying to make my iOS 5 app iOS 6 compatible. I cannot get the orientation stuff to work right. I am unable to detect when a rotation is about to happen. Here is the code I am trying:
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
The new supportedInterfaceOrientation: method gets called just fine. The shouldAutorotate method, however, will not fire. I need to do some image swapping on rotate, but I can't get any indication that a rotation is about to occur.
Thanks in advance.
Upvotes: 48
Views: 49104
Reputation: 1607
If you use UINavigationController as the basis for an app. I create a category of UINavigationController and call it "UINavigationController+autoRotate". Put this in your UINavigationController+autoRotate.h:
#import <UIKit/UIKit.h>
@interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
@end
Put this in UINavigationController+autoRotate.m:
#import "UINavigationController+autoRotate.h"
@implementation UINavigationController (autoRotate)
- (BOOL)shouldAutorotate
{
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
@end
Upvotes: 0
Reputation: 846
See if you are getting the following error when your App starts.
Application windows are expected to have a root view controller at the end of application launch
If so the way to fix it is by making the following change in the AppDelegate.m
file (although there seem to be a number of answers how to fix this):
// Replace
[self.window addSubview:[navigationController view]]; //OLD
// With
[self.window setRootViewController:navigationController]; //NEW
After this shouldAutoRotate
should be correctly called.
Upvotes: 80
Reputation: 4919
If your viewController
is a child viewController
in a UINavigationController
then you can do the following:
UINavigationController
shouldAutoRotate
in your subclasstopViewController
this message when this method get called// This Method is inside your UINavigationController
subclass
- (BOOL)shouldAutorotate
{
if([self.topViewController respondsToSelector:@selector(shouldAutorotate)])
{
return [self.topViewController shouldAutorotate];
}
return NO;
}
Upvotes: 10
Reputation: 2537
I'm using iOS 7 but I believe my case may be helpful to others.
I have a deep view controller hierarchy rooted with UITabBarController. The only place where shouldAutorotate is guaranteed to be called is inside the UITabBarController. So I simply subclass UITabBarController and put my rotation control logic inside my shouldAutorotate method.
Upvotes: 1
Reputation: 27608
This is how I would do it
if you want to check which is current orientation then add this line to your viewconrtoller.m file
#define isPortrait [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown
then where you want to check orientation ,write condition like below
- (void)viewDidLoad
{
if(isPortrait)
{
//portrait mode....
NSLog(@"its in IsPotraitMode");
}
else
{
//landscape mode....
NSLog(@"its in IsLandscapeMode");
}
}
Upvotes: 0
Reputation: 10195
When using UINavigationController as the basis for an app I use the following subclass to give me the flexibility to allow the top most child viewcontroller to decide about rotation.
@interface RotationAwareNavigationController : UINavigationController
@end
@implementation RotationAwareNavigationController
-(NSUInteger)supportedInterfaceOrientations {
UIViewController *top = self.topViewController;
return top.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate {
UIViewController *top = self.topViewController;
return [top shouldAutorotate];
}
@end
Upvotes: 45
Reputation: 33421
That method is not the correct way to determine that. The correct method is willRotateToInterfaceOrientation:duration:
The should rotate to orientation (as opposed to shouldAutorotate) method is deprecated and will no longer be called as of iOS 6, but it was not meant to be used the way you were using it anyway.
EDIT Response to repeated downvotes. Please explain why using the method I indicated is not an (to quote OP) "indication that a rotation is about to occur." The content of the question and the title are mismatched.
Upvotes: 15
Reputation: 49
I was also getting the following error when your App starts.
"Application windows are expected to have a root view controller at the end of application launch"
I am using a UISplitViewController *splitViewController
If so the way to fixed it is by making the following change in the AppDelegate.m file:
Replace
[self.window addSubview:[splitViewController view]];
With
[self.window setRootViewController:splitViewController];
After this shouldAutoRotate
was called and worked correctly.
Upvotes: 1
Reputation: 1595
It looks that on iOS 6 the container navigations controller doesn't consult child view controllers when rotating:
in iOS 6 release notes :
Now, iOS containers (such as UINavigationController) do not consult their children to determine whether they should autorotate. By default, an app and a view controller’s supported interface orientations are set to UIInterfaceOrientationMaskAll for the iPad idiom and UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
This behavior is easy to test. What I did is to use the same custom view controller
In the first case everything is decided in the custom navigation controller by the combination of shouldAutorotate
and supportedInterfaceOrientations
given that supportedInterfaceOrientations
agrees with the supported orientations of the application.
In the second case even if the supportedInterfaceOrientations
of the custom view controller is called by the UIPageViewController the return value is not taken in to consideration. It works if the two methods are overwritten in a subclass of the UIPageViewController. I am not sure about the side effects of that as this class is not supposed to be subclassed.
Upvotes: 10