iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates)
If your are using a UINavigationController as the root window controller, it will be its shouldAutorotate
& supportedInterfaceOrientations
which would be called.
Idem if you are using a UITabBarController, and so on.
So the thing to do is to subclass your navigation/tabbar controller and override its shouldAutorotate
& supportedInterfaceOrientations
methods.
iOS 6 rotations: supportedInterfaceOrientations doesn´t work?
If your ViewController is a child of a UINavigationController or UITabBarController, then it is the parent that is your problem. You might need to subclass that parent view controller, just overriding those InterfaceOrientation methods as you've shown in your question
EDIT:
Example for portrait only TabBarController
@interface MyTabBarController : UITabBarController
{
}
@end
@implementation MyTabBarController
// put your shouldAutorotateToInterfaceOrientation and other overrides here
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
@end
supportedInterfaceOrientations not working
Here is how I do it.
Make a UINavigationController parent class.
inside you UINavigationController (parent) override these methods like:
- (NSUInteger)supportedInterfaceOrientations
{
if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientationsForThisContorller)])
{
return(NSInteger)[self.topViewController performSelector:@selector(supportedInterfaceOrientationsForThisContorller) withObject:nil];
}
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
if([self.visibleViewController respondsToSelector:@selector(shouldAutorotateNow)])
{
BOOL autoRotate = (BOOL)[self.visibleViewController
performSelector:@selector(shouldAutorotateNow)
withObject:nil];
return autoRotate;
}
return NO;
}
Now your NavigationController should be a subclass of the UINavigationContorller parent
Swift 3:
Inside your UINavigationController subclass do this
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
get {
return self.topViewController?.supportedInterfaceOrientations ?? .all
}
}
override var shouldAutorotate: Bool {
return self.topViewController?.shouldAutorotate ?? false
}
Update
Taken from Matt's answer if you don't want to subclass:
first: make your viewController a delegate of the navigationController in viewDidLoad
self.navigationController?.delegate = self
Then declare UIViewController extension to respond to the delegate method as shown below:
extension UIViewController: UINavigationControllerDelegate {
public func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
return navigationController.topViewController?.supportedInterfaceOrientations
}
}
iOS6 Preferred Interface Orientation Not Working
It would appear Apple have removed the ability to push a view in a specific orientation. preferredInterfaceOrientationForPresentation
does get called, but only when popping back or presenting a view controller. I had to present my landscape view rather than push it, and set shouldAutoRotate
= NO.
Refer to: In iOS6, trouble forcing ViewController to certain interfaceOrientation when pushed on stack for more details.
iOS 6 Rotation issue - No rotation from Presented Modal View Controller
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:,
anddidRotateFromInterfaceOrientation:
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.
iOS 6 ViewController is rotating but shouldn't
If you want all of our navigation controllers to respect the top view controller you can use a category. I've found it easier than subclassing.
@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
UITabBarController Rotation Issues in ios 6
Zack, I ran into this same issue. It's because you have your viewController embedded inside of a TabBar Controller or UINavigationController and the calls to these methods are happening inside those instead of your normal View (Changed in iOS6).
I ran into this issue because I was presenting a viewController embedded inside a UINavigationController on all my modal views that had Navigation to different views (Signup Process, Login, etc).
My simple fix was to create a CATEGORY for UINavigationController that includes these two methods. I have shouldAutorotate returning NO anyway because I don't want my modal views rotating. Your fix may be this simple, give it a try. Hope it helps.
I created a category and named it autoRotate and selected theUINavigationController option. The M+H file are below.
#import "UINavigationController+autoRotate.h"
@implementation UINavigationController (autoRotate)
-(BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
@end
... and the category .h:
#import <UIKit/UIKit.h>
@interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
@end
presentViewController not supporting orientation in iOS 6
You must include this in you application delegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
Also make sure the View Controller's both have the following, works fine for me.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
The documentation also says that UINavigationController's
doesn't query its top View Controller for orientations supported, although an Apple engineer over on the Developer Forums did say so... it seems that it does not. Therefore you should add a category for UINavigationController
, this is the one I use:
#import "UINavigationController+autorotate.h"
@implementation UINavigationController (autorotate)
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
@end
For more information how AutoRotate works on iOS 6 check out this answer
iOS 6 shouldAutorotate: is NOT being called
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.
iOS 6 UITabBarController supported orientation with current UINavigation controller
Subclass your UITabBarController
overriding these methods:
-(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;
}
Subclass your UINavigationController
overriding these methods:
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
Then implement these methods in your viewControllers that you do not want to rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And for viewControllers that you do want to rotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Your tabbarController should be added as the RootviewController of the app window. If you plan to support the default orientations, all but upsidedown is default for iPhone, then you do not need to do anything else. If you want to support upside-down or if you do not want to support another of the orientations, then you need to set the appropriate values in app delegate and/or info.plist.
Related Topics
Generating an Unsigned IPA iOS Application
How to Determine Device Type from Swift? (Os X or iOS)
iOS Autolayout Vertically Equal Space to Fill Parent View
Show Uipickerview Text Field Is Selected, Then Hide After Selected
Pod Error in Xcode "Id: Framework Not Found Pods"
Crashlytics iOS - Log Caught Exception
Firebase: Cannot Upload Production Apns Certificate
Xcode 7 How to Refresh Provisioning Profiles
How to Create and Send the JSON Data to Server Using Swift Language
How to Do a Live Uitextfield Count While Typing (Swift)
How to Change Uibutton Title Color
Uicollectionview Select and Deselect Issue
Disabled Uibutton Not Faded or Grey
Allow Uiscrollview and Its Subviews to Both Respond to a Touch
Swift Failed with Exit Code 1 While Compiling in Xcode - Possibly Related to Bridging-Headers
Swift 3: Expression Implicitly Coerced from 'Uiview' to Any
Xcode6 Error: "No Matching Provisioning Profiles Found for Application"