Support different orientation for only one view iOS 6 - objective-c

I want to rotate ONLY one of my views within my app to either landscape left or landscape right. All my other views are in portrait mode and I have set my app to support only portrait mode. With orientation being changed in iOS 6, I am not sure how to do this. I have tried the following posted below. Can anyone tell me what I am doing wrong? Thanks!
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
I have also tried:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
return YES;//UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
-(void)didRotate:(NSNotification *)notification {
UIDeviceOrientation orientation = [[notification object] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
} else if (orientation == UIDeviceOrientationLandscapeRight) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortrait) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
}
}

This worked for me How to force a UIViewController to Portrait orientation in iOS 6
Create a new category from UINavigationController overriding the rotating methods:
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
#end

There are changes in iOS 6 regarding handling view rotations. Only orientations defined in apps Info.plist are supported. Even if you are returning other ones.
Try to select all orientations as supported in your project.
Handling View Rotations
In iOS 6, your app supports the interface orientations defined in your app’s Info.plist file. A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations. Generally, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate in directly in decisions about what rotations are supported. The intersection of the app’s orientation mask and the view controller’s orientation mask is used to determine which orientations a view controller can be rotated into.
You can override the preferredInterfaceOrientationForPresentation for a view controller that is intended to be presented full screen in a specific orientation.
In iOS 5 and earlier, the UIViewController class displays views in portrait mode only. To support additional orientations, you must override the shouldAutorotateToInterfaceOrientation: method and return YES for any orientations your subclass supports. If the autoresizing properties of your views are configured correctly, that may be all you have to do. However, the UIViewController class provides additional hooks for you to implement additional behaviors as needed. Generally, if your view controller is intended to be used as a child view controller, it should support all interface orientations.
When a rotation occurs for a visible view controller, the willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation: methods are called during the rotation. The viewWillLayoutSubviews method is also called after the view is resized and positioned by its parent. If a view controller is not visible when an orientation change occurs, then the rotation methods are never called. However, the viewWillLayoutSubviews method is called when the view becomes visible. Your implementation of this method can call the statusBarOrientation method to determine the device orientation.
(C) Apple Docs: UIViewController

Follow the below steps
Create subclass of UINavigationController overriding the rotating methods.
In AppDelegate, create a BOOL islandscape property.
When a view is pushed/poped/present/dismiss, adjust this BOOL value.
Sample Project
I created a sample project for this which is working perfectly. Download and integrate in your project: https://www.dropbox.com/s/nl1wicbx52veq41/RotationDmeo.zip?dl=0

I have a:
TabbarController -> NavigationController -> ViewController -> ViewController
I Subclassed UITabBarController and add....
-(NSUInteger)supportedInterfaceOrientations{
if (self.selectedIndex >= 0 && self.selectedIndex < 100) {
for (id vC in [[self.viewControllers objectAtIndex:(unsigned long)self.selectedIndex] viewControllers]) {
if ([vC isKindOfClass:[CLASS_WHICH_SHOULD_ALLOW class]]) {
return UIInterfaceOrientationMaskPortrait + UIInterfaceOrientationMaskLandscape;
}
}
}
return UIInterfaceOrientationMaskPortrait;
}

I have been searching for the solution for hours!
So after implementing the needed methods everywhere. shouldAutorotate doesn't need to be set to YES because it is already set as default:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
When it is time to show the UIViewController which needs the orientation different than the other views, I created a UIStoryboardSegue with this implementation inside:
#import "Showing.h"
#implementation Showing
- (void)perform{
NSLog(#"Showing");
UIViewController *sourceVC = self.sourceViewController;
UIViewController *presentingVC = self.destinationViewController;
[sourceVC.navigationController presentViewController:presentingVC
animated:YES
completion:nil];
}
#end
Inside the UIStoryboard I connected the views with this segue (showing):
It is just important, you are using
presentViewController:animated:completion:
AND NOT
pushViewController:animated:
otherwise the orientation won't be determined again.
I had been trying things like
[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
OR this one inside the UIViewController where the orientation should change, and I also tryied to call it inside my custom UIStoryboardSegues before presentingViewController and dismissViewController:
[UIViewController attemptRotationToDeviceOrientation];
OR
NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:#"orientation"];
But no one of them worked. Of course the last example shouldn't be an option, because if apple will change anything of their api this could cause problems inside your app.
I also tried to use the AppDelegate method and always determine the orientation inside this method after looking for the correct UIInterfaceOrientation of the actual visibleViewController but then it sometimes happened to crash when switching from one to another orientation. So I'm still wondering why its made so complicated and there seems also not to be any documentation where it is explained correctly.
Even following this part didn't help me.

UIViewController+OrientationPermissions.h
#interface UIViewController (OrientationPermissions)
+ (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations;
+ (UIInterfaceOrientationMask)supportedOrientations;
#end
UIViewController+OrientationPermissions.m
#implementation UIViewController (OrientationPermissions)
static UIInterfaceOrientationMask _supportedOrientations;
+ (void)setSupportedOrientations: (UIInterfaceOrientationMask)supportedOrientations {
_supportedOrientations = supportedOrientations;
}
+ (UIInterfaceOrientationMask)supportedOrientations {
return _supportedOrientations;
}
#end
In your UIApplication delegate
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [UIViewController supportedOrientations];
}
Then on a desired view controller do something like
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[UIViewController setSupportedOrientations:UIInterfaceOrientationMaskAll];
}
Don't forget to reset mask before leaving this view controller
Note, if you are using UINavigationController or UITabBarController, see https://stackoverflow.com/a/28220616/821994 how to bypass that

Defiantly work Please try.
I solve after 2 days
//AppDelegate.m - this method is not available pre-iOS6 unfortunately
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m - return whatever orientations you want to support for each UIViewController
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Related

How to load UIView in Portrait mode irrespective of device orientation - IOS 6

I am working on iOS 6 application, I have handled the UIview rotation using following methods...
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL) shouldAutorotate {
return YES;
}
Everything is working fine, problem is initial view loading is decided based on device orientation, for e.g.: if I keep my device in landscape mode even though I have returned as forcibly portrait in supportedInterfaceOrientations view is showing in landscape only, once device is rotated to portrait after that it is not going to landscape mode, all working fine. Is it possible to load a View at certain mode irrespective of the device orientation?
I have googled and nothing worked.
NOTE: I am using navigation controller. And I have added category for UINavigationController.
// Custom categoy to handle orientation in IOS6
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
thanks
Use this method:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
}
Add this method along with category for UINavigationController in appDelegate.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
//check for which controller u need these methods
if([navigationController.visibleViewController isKindOfClass:[yourViewController class]]) //provide specific view controller where u want protrait
{
[navigationController shouldAutorotate];
[navigationController supportedInterfaceOrientations];
[navigationController preferredInterfaceOrientationForPresentation];
}
return UIInterfaceOrientationMaskAll;
}
Note : remove from all viewController if u have added category for UINavigationController. It should be only in appDelegate.

Allow autorotation on just one view controller

In my project I have allowed only portrait rotation, but for one ViewController I would like to enable also landscape. I'm presenting this ViewController as ModalViewController, I've tried using methods - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation or iOS 6 methods like -(NSUInteger) supportedInterfaceOrientations but nothing actually worked. The view didn't rotate although those methods got called.
After this I've tried to rotate it by myslef with listening to those notifications :
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
but even though I was able to manually rotate the view in method didRotate: it's very messy and I can't rotate the StatusBar.
I would really like to use standard methods like shouldAutorotateToInterfaceOrientation, but I don't know how. Anyone?
Add this in your app delegate.m
# pragma mark - Rotation
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([self.window.rootViewController isKindOfClass:[MVYSideMenuController class]]) {
// Get topmost/visible view controller
UIViewController *currentViewController = [self.window.rootViewController.childViewControllers lastObject];
// Check whether it implements a dummy methods called canRotate
if ([currentViewController respondsToSelector:#selector(canRotate)]) {
// Unlock landscape view orientations for this view controller
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
// Only allow portrait (standard behaviour)
return UIInterfaceOrientationMaskPortrait;
}
-(void)canRotate
{
}
and then add this method
-(void)canRotate
{
// just define the method, no code required here
}
in every ViewController (.m files) where you want to provide rotation. You can also include here -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method to react when the device rotates:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch (orientation) {
case 1:
case 2:
//NSLog(#"portrait");
break;
case 3:
case 4:
//NSLog(#"landscape");
break;
default:
//NSLog(#"other");
break;
}
}
Subclass a navigation controller for your screen that requires rotation.
In the .m
// Older versions of iOS (deprecated) if supporting iOS < 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
// iOS6
- (BOOL)shouldAutorotate {
return YES;
}
// iOS6
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
This overrides the rotation methods set in the summary page for iOS 6.
In iOS 6 the view controllers only look to there parent or root controller for rotation methods
can't you just call the shouldAutoRotateToInterfaceOrientation in the viewDidLoad and viewWillAppear like so:
[self shouldAutorotateToInterfaceOrientation];
that should call the method if its in your ViewController
Implement is in all controller and Return on that interfaceOrientation which you need for a specific controller
For All
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation{
return YES;
}
For Landscape
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
For Portrait
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}

Force Landscape Orientation on iOS 6 in Objective-C

I have a master view controller that's inside a UINavigationController. In that master view controller, I have a button that pushes a detail view controller that has a UIWebView inside of it. I want this detail view controller to be on landscape mode when it's loaded. Going back to the master view controller, it forcibly goes back again to portrait mode. I'm running iOS 6 on this.
I have seen the other similar questions but it's not working on my end. I have created a LandscapeViewController that's a subclass of UIViewController where I have written these methods:
#pragma mark - Orientation Methods
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate
{
return YES;
}
This is my code when I push the detail view controller:
DetailViewController *detailVC = [[DetailViewController alloc]
initWithNibName:#"DetailViewController"
bundle:nil];
[self.navigationController pushViewController:detailVC
animated:YES];
I'm thinking on where to subclass my LandscapeViewController on the code above to make it work or on how to properly subclass and push my detail view controller. I can also present my detail view controller modally if it's not possible for the navigation controller to push my detail view controller from portrait to landscape. Where am I doing it wrong?
Considering:
View A: Portrait only - View B: Landscape only
I couldn't do it in the navigation controller. Instead what I did was to open a modal view from view A to view B and force a new navigation controller into this view.
This is working for me in iOS5+.
You need to create a category for the navigation controller like this:
UINavigationController+Rotation_IOS6.h
#import <UIKit/UIKit.h>
#interface UINavigationController (Rotation_IOS6)
- (BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
#end
UINavigationController+Rotation_IOS6.h
#import "UINavigationController+Rotation_IOS6.h"
#implementation UINavigationController (Rotation_IOS6)
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
#end
In AppDelegate.m add:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
Then in View A:
- (BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
also in View A to open View B do this:
ViewB *vc = [[ViewB alloc] initWithNibName:#"ViewB" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:navigationController animated:YES completion:nil];
And, finally, in View B
- (BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
They kinda screwed the pooch in iOS 6 with regard to this. Here's what I've figured out so far:
First off, Apple added the "Supported Interface Orientations" buttons with Xcode 4.5. This corresponds to the "Supported interface orientations" attribute in _info.plist. These buttons must be toggled to the correct choices before any of the rest will work. (If the buttons seem to refuse to toggle it's likely because the info.plist is locked by CVS or some other process.)
Next, the property .window.rootViewController must be set, and must point to the "bottom" view controller in the stack. Generally this will be either a navigation controller or a tab controller.
If the desire is to disable all rotation, this can be done using the buttons, or one can implement, in the "bottom" view controller, the "shouldAutorotate" method and have it return NO. (If the method is omitted then the default is YES.)
In spite of having autorotation disabled with shouldAutorotate, if there is a MPMoviePlayerViewController being displayed, that will autorotate. Only toggling the supported interface orientation buttons appears to prevent this.
If one wants to conditionally autorotate other view controllers it gets messier. Basically, your "bottom" view controller must implement the supportedInterfaceOrientations method and return, based on the current topViewController, the appropriate bit mask. This can be done with a routine that queries the topViewController's old "shouldAutorotateToInterfaceOrientation" method, but it's a bit ugly. And even though this scheme doesn't require modifying the rotating view controller's code, you DO need to modify the VC just "below" the rotated one to implement "supportedInterfaceOrientation", or else that view will be rotated on return. (At least this is a simple copy/paste.) No one seems to have come up with a better, more general scheme, though.

iOS: Change interface orientation when pop view controller

All view controllers in my app are working only in portrait orientation except one which can be portrait or landscape oriented.
I have some usage scenario like following:
I push controller which works in both orientations to UITabBarController
User change orientation from portait to landscape
User press "back button"
After these actions application remains in landscape orientation and does not change it automatically to portrait.
I control view controller orientation using supportedInterfaceOrientations (I use iOS 6.0). What I do wrong? How can I get correct behaviour when application automatically change orientation to allowed when user press back button? Thank you for answer!
In iOS 6 (and possibly earlier), if a view controller is offscreen when the device rotates, it does not get any notification. Nor does it get sent willAnimateRotationToInterfaceOrientation:duration: when it becomes the top view controller.
You need to keep track of the current orientation of the view controller and check the device orientation in viewWillAppear:. If they are different, you can use willAnimateRotationToInterfaceOrientation:duration: to set it correctly.
Since this is something you are likely to do a lot, you may want to create a generic superclass that your view controllers inherit from.
A typical solutions is:
#implementation MyHandlesOffscreenRotationController
{
BOOL isShowingPortrait;
}
- (void) viewDidLoad
{
[super viewDidLoad];
isShowingPortrait = UIInterfaceOrientationIsPortrait(
[[UIApplication sharedApplication] statusBarOrientation]);
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
BOOL currIsPortrait = UIInterfaceOrientationIsPortrait(
[[UIApplication sharedApplication] statusBarOrientation]);
if ((isShowingPortrait && !currIsPortrait) ||
(!isShowingPortrait && currIsPortrait)) {
[self willAnimateRotationToInterfaceOrientation:
[[UIApplication sharedApplication] statusBarOrientation]
duration:0.0f];
}
}
#end
Just override -(BOOL)shouldAutoRotate and - (NSUInteger)supportedInterfaceOrientations inside a UINavigationController category, then ViewController will force rotate to its supported orientation after pop from other ViewController.
#implementation UINavigationController (Rotate)
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
#end
iOS 9 and above
At the time of pop just write the below-mentioned code in your viewWillAppear method.
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]forKey:#"orientation"];
With this, your view will appear in portrait mode.
P.L. has a nice solution in this topic: Present and instantly dismiss an empty modal view controller which allows only portrait | landscape
How to change the device orientation programmatically in iOS 6

iOS 6 Rotation issue - No rotation from Presented Modal View Controller

I have a MainViewController which has a button which pushes a new view (InfoViewController), via flip horizontailly. like so:
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
The MainView Controller supports Portrait and PortraitUpsideDown. Like so:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait |
UIInterfaceOrientationMaskPortraitUpsideDown);
}
In my InfoViewController it also states the above code. In my AppDelegate it has this in the LaunchOptions:
[self.window setRootViewController:self.mainViewController];
In my app.plist file it supports all orientations. This is because other views need to support landscape as well. So On my MainViewController and InfoViewController I need only Portrait and PortraitUpsideDown. But on another view I need all orintations.
My MainViewController works fine, but my InfoViewController is working for all orientations.
I am having extreme diffulty trying to get this to work in iOS6. I have researched other posts and tried the assistance other people have provided, but had no luck whatsoever. Please can someone help me acheive this thank you. And I'm a Objective-C newbie :p
Don´t support all orientations in your app plist file, only those that your root view controller supports.
Autorotation is changing in iOS 6. In iOS 6, the shouldAutorotateToInterfaceOrientation: method of UIViewController is deprecated. In its place, you should use the supportedInterfaceOrientationsForWindow: and shouldAutorotate methods:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
Modal ViewControllers no longer get rotation calls in iOS 6:
The willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:, and
didRotateFromInterfaceOrientation: methods are no longer called on any view controller that makes a full-screen presentation over
itself—for example those that are called with: presentViewController:animated:completion:.
You can let the view controller that presents your modal view controller inform it of rotation.
Also, now you use: presentViewController:animated:completion: to present the view controller. presentModalViewController:animated: is deprecated which you use in the code.
I have solved similar problems, while using tab bar controller.
Subclass UITabBarController. Implement these methods:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
- (BOOL)shouldAutorotate
{
NSLog(#"Orientation:%d", [[UIDevice currentDevice] orientation]);
for (UIViewController *viewController in self.viewControllers) {
[viewController shouldAutorotate];
}
return YES;
}
If you want to handle rotations in controllers inside tabbarcontroller, in each of the controllers in the tab bar controller implement those methods too and write code to handle orientation change. If you don't want to handle it, then you don't need to implement those methods. TabBarControllers methods will always run when orientation changes. Even twice for unknown reason.
Yes, and don't forget to delete all shouldAutorotate methods. I moved to the new orientation model completely. If you want to make them remain, probably, it will be harder.
Make a category by subclassing UINavigationController and implement following methodes
in .h file
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
in .m file
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
and implement following methodes in the view controller class ,class u want to enable rotation
-(NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown);
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
add this code on Subclass UITabBarController .m
#implementation UINavigationController (rotation)
//temp hack for iOS6, this allows passing supportedInterfaceOrientations to child viewcontrollers.
- (NSUInteger)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
#end
#implementation NameClassUITabBar
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
#end
Here I've posted my solution/experince in tab bar controller with rotations:
http://luterr.blogspot.sg/2015/04/example-code-uiinterfaceorientationmask.html