Force Landscape Orientation on iOS 6 in Objective-C

I have a main view controller that is inside a UINavigationController. In this main view controller, I have a button that pushes a detailed view controller that has a UIWebView. I want this detail view controller to be in landscape mode at boot time. Returning to the main view controller, he is forced to return to portrait mode. I am running iOS 6 on this.

I saw other similar questions, but it did not work on my end. I created a LandscapeViewController, which is a subclass of UIViewController, where I wrote these methods:

#pragma mark - Orientation Methods - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; } - (BOOL)shouldAutorotate { return YES; } 

This is my code when I click the detail view controller:

 DetailViewController *detailVC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; [self.navigationController pushViewController:detailVC animated:YES]; 

I am thinking about where to subclass my LandscapeViewController to the code above to get it working, or how to properly subclass and push my detail view controller. I can also imagine the detail view controller if the navigation controller cannot push my detail view manager from portrait to landscape. Where am I doing this wrong?

+7
source share
2 answers

Considering: View A: portrait only - view B: landscape only

I could not do this in the navigation controller. Instead, I decided to open a modal view from view A to view B and force a new navigation controller in that view.

This works for me in iOS5 +.

You need to create a category for the navigation controller as follows:

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); } 
+8
source

They kind of screwed up pooch in iOS 6 regarding this. Here is what I have guessed so far:

First, Apple added the “Supported Interfaces” buttons with Xcode 4.5. This corresponds to the "Supported Interface Orientations" attribute in _info.plist. These buttons must be switched to the correct selection before any of the others will work. (If the buttons seem to refuse to switch, probably because the info.plast is blocked by CVS or some other process.)

Next, the .window.rootViewController property must be set and must point to the "bottom" view controller on the stack. This will usually be either a navigation controller or a tab controller.

If you want to disable all rotation, this can be done using the buttons, or you can implement the "shouldAutorotate" method in the "lower" type controller and return NO to it. (If the method is omitted, the default value is YES.)

Although autorotation is disabled with shouldAutorotate, if the displayed MPMoviePlayerViewController is displayed, it will autorotate. Only to switch the supported interface orientation buttons to prevent this.

If you want to conditionally authorize other view controllers, it becomes messy. Basically, your "lower" view controller should implement the supportedInterfaceOrientations method and return the corresponding bitmask based on the current topViewController. This can be done using a procedure that calls the old method "shouldAutorotateToInterfaceOrientation" topViewController, but it's a little ugly. Although this scheme does not require modification of the controller code of the rotating view, you only need to change the VC “below” the rotated one to implement the “supportedInterfaceOrientation”, otherwise this view will be rotated by return. (At least this is a simple copy / paste.) However, no one seems to have come up with a better, more general outline.

0
source

All Articles