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 onl
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
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.
[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
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 thesupportedInterfaceOrientations
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 theshouldAutorotateToInterfaceOrientation:
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, theUIViewController
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:
, anddidRotateFromInterfaceOrientation:
methods are called during the rotation. TheviewWillLayoutSubviews
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, theviewWillLayoutSubviews
method is called when the view becomes visible. Your implementation of this method can call thestatusBarOrientation
method to determine the device orientation.
(C) Apple Docs: UIViewController
Follow the below steps
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