shouldAutorotateToInterfaceOrientation is not working in iOS 5 - ios

I saw this stackoverflow post:shouldAutorotateToInterfaceOrientation is not working in iOS 6. The answer was to add a category called RotationIn_IOS6. I have done that and the views for the different viewcontrollers are working correctly in iOS6. The problem is in iOS5.
I only need a few views to rotate in all directions, the rest should be in portrait or either PortraitUpsideDown. The problem i face is that either all don't rotate(code1) or after it rotates to landscape, it remains in the same orientation until you rotate back to portrait(code2).
Code1:
#implementation UINavigationController (RotationIn_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
#end
Code 2:
#implementation UINavigationController (RotationIn_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if([self.visibleViewController isKindOfClass:[MyClassToRotate class]])
{
return [self.visibleViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
else
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
Need some guidance on this. Not sure how to solve this.
EDIT:
Code3:
1) Removed the shouldAutorotateToInterfaceOrientation from the Category.
2) Added this code to my particular class
- (BOOL)shouldAutorotate
{
//returns true if want to allow orientation change
return TRUE;
}
- (NSUInteger)supportedInterfaceOrientations
{
//decide number of origination tob supported by Viewcontroller.
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
//from here you Should try to Preferred orientation for ViewController
return TRUE;
}
Result -> All the viewcontroller locked in portrait. Cannot access PortraitUpsideDown. Once in my viewcontroller, it can rotate, but when you get out of the viewcontroller, locked in landscape..
EDIT 2:
Each viewcontroller contains these code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return NO;
}

No need to override shouldAutorotateToInterfaceOrientation: in the navigation controller category instead for iOS 5 each of your view controller should implement shouldAutorotateToInterfaceOrientation: with the supported orientation. The supported orientations determined by the container controller(navigation controller) is only in the iOS6 and above. In lower version it will call the shouldAutorotateToInterfaceOrientation: of the child view controller which is going to display

To solve that problem i've subclassed UINavigationController instead of use a category:
MyNavigationcontroller.h
#import <UIKit/UIKit.h>
#interface MyNavigationcontroller : UINavigationController
#end
MyNavigationcontroller.m
#import "MyNavigationcontroller.h"
#interface MyNavigationcontroller ()
#end
//Set your init...
-(BOOL)shouldAutorotate {
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(#"YourClass")])
return YES;
}
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(#"YourClass")]) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortraitUpsideDown;
}
#end
Then in each viewcontroller override:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationMaskPortraitUpsideDown);//or your orientation
}
Then, at launch, in the didFinishLaunchingWithOptions: of your app delegate:
NSString *reqSysVer = #"6.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
self.navigationController = [[MyNavigationcontroller alloc] initWithRootViewController:masterViewController];//IOS 6
}else{
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
}
self.window.rootViewController = self.navigationController;

The simplest way is Target->General->Deployment Info and tick the orientations you want. E.g. tick only portrait and the app will not auto rotate.

Related

Forcing portrait orientation for a view controller is not working

My app supports all interface orientations, but I want a certain view to be shown only in portrait. I have this implementation of an UINavigationController subclass:
#implementation CustomNavigationController
- (BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
// More methods
#end
Then, for its root view controller, I have implemented:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
This prevents the view of the view controller from being rotated to landscape when it is in portrait, but when I navigate to this view being the device already in landscape, and I have been previously in a view which do rotates to landscape, I see this view in landscape as well.
How could I solve this scenario?

Going back from a view and changing the orientation

With SDK8.1 I allow Portrait orientation, Landscape left and right on .plist. I have
1) A navigation controller
#implementation OrientationRespectfulNavigationController
- (BOOL)shouldAutorotate
{
BOOL retVal = [super shouldAutorotate];
if (self.topViewController)
retVal = [self.topViewController shouldAutorotate];
return retVal;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger retVal = [super supportedInterfaceOrientations];
if (self.topViewController)
retVal = [self.topViewController supportedInterfaceOrientations];
return retVal;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation retVal = [super preferredInterfaceOrientationForPresentation];
if (self.topViewController)
retVal = [self.topViewController preferredInterfaceOrientationForPresentation];
return retVal;
}
2) UIViewController A
-(BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
2) UIViewController B
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait;
}
So, I start the app in portrait. I see the ViewController A. Then I push to ViewController B also in portrait. Then I rotate the mobile and B change to landscape. OK. But, why when I go back ViewController A appears in landscape? How I can force A still always in portrait? I prove a lot of things and I can't find a solution in stackoverflow
Thanks

Handling Orientation in Ios7 for specific ViewControllers

I'm creating a ebook application in which i have only given all orientation's to two of the ViewControllers.
i was abel to successfully set the orientation to the two ViewControllers and perform the Rotation for the first time.but later when i load the view controller with new book the rotation is not working properly.
i used the methods:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
//code for landscape
}
else{
//code for protrait.
}
}
- (BOOL)shouldAutorotate{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return (UIInterfaceOrientationMaskAll);
}
Try to handle rotation on your UINavigationControllers, your exact code on a UINavigationController subclass is correct. And make sure your UIViewControllers are set as childViewControllers of your new UINavigationControllers.
And remember you need to set your supported orientations with the key "Supported interface orientations" on your info.plist.
Create a SubClass of UINavigationController
#interface BaseNavigationController : UINavigationController
#end
#implementation BaseNavigationController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
BOOL shouldAutorotateBool = NO;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
// iOS6/7 support
- (NSUInteger) supportedInterfaceOrientations {
NSUInteger interfaceOrientation = UIInterfaceOrientationMaskPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(BOOL)shouldAutorotate
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
-(BOOL) isRotate
{
if ([[self.viewControllers lastObject] isMemberOfClass:NSClassFromString(#"VideoVC")]) {
return YES;
}
return NO;
}
#end
And in that particular viewController:
#import "VideoVC.h"
#interface VideoVC ()
#end
#implementation VideoVC
#pragma mark- Methods for device orientation handling
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
- (BOOL)shouldAutorotate
{
return YES;
}
#end

Landscape and portrait orientations in only one viewcontroller

In my app I am using MPMoviePlayerController. I need to display movie player in both landscape and portrait orientations. I only want movie player to display like this and other screens should only be portrait oriented. I am stuck and getting no solutions. From settings I've checked three modes as shown below.
I am using ios 7 and xcode 5. Thanks
In your ViewController which contains MPMoviePlayerController, implement this (iOS6 and above):
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll; //allow rotate landscape, portrait
}
In other viewControllers:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown; // portrait only
}
To iOS version is lower than 6, implement this method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- (BOOL)shouldAutorotate
Note that: ViewController which contain above VCs should implement above methods
Create Inherited class of NavigationController
BaseNavigationController.h
import
#interface BaseNavigationController : UINavigationController
#end
BaseNavigationController.m
pragma mark- Orientation changes handling
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate])
{
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
// iOS6/7 support
- (NSUInteger) supportedInterfaceOrientations {
NSUInteger interfaceOrientation = UIInterfaceOrientationMaskPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(UIInterfaceOrientation) preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(BOOL)shouldAutorotate
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate])
{
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
-(BOOL) isRotate
{
if ([[self.viewControllers lastObject] isMemberOfClass:NSClassFromString(#"VideoVC")]) {
return YES;
}
return NO;
}
**And the particular viewController use the following Code for orientation**
pragma mark- Methods for device orientation handling
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeLeft;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Best way to change orientation only for the MoviePlayer
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
First you should use methods for the iOS6 presented in UIViewController documentation if you are making your app for iOS6. Orientation method like shouldAutorotateToInterfaceOrientation is deprecated in iOS6, alternate method for iOS6 is shouldAutoRotate. You should only use the old method if your app is supporting also iOS5.
Second If you are using UINavigationcontroller in your application and you need to have different interface orientations then navigationController could mess up the interface orientation in the application. Possible solution (worked for me) is to implement a custom UINavigationController and override the interface orientation methods within that custom UINavigationController class, this will make your viewControllers rotate according to the orientation you set because your controllers are pushed from the UINavigationController. Don't forget to add those methods in your particular viewController also.
CustomNavigationController.h
#interface CustomNavigationController : UINavigationController
#end
CustomNavigationController.m
#implementation CustomNavigationController
//overriding shouldRotate method for working in navController
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}

IOS - fix portrait viewcontroller inside multiple tabbar and navigation

I have a diagram very complicated, and I want to fix portrait UIViewController inside multiple TabBarController and NavigationController, I'm using this code in UIViewController do fix TabBar and Navigation:
#implementation UINavigationController (LoginIphone)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
#implementation UITabBarController (ChannelViewController)
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
and this code inside do fix UIViewController but it doesn't work.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
Anyone have solution for this problem, thank to read this article!
Your supportedInterfaceOrientations method should be:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
project Targets --> click on "Summary" tab and choose your Orientation in "Supported interfaces Orientations"

Resources