I have a UIViewController
, which is presented modally (full screen) and I would like to disable autorotation in that view. I do not want to restrict it to landscape or portrait, just would like it to stay in whatever orientation it was originally presented.
On iOS 6 it was sufficient to just override the method:
- (BOOL)shouldAutorotate {
return NO;
}
And it did exactly what I wanted. On iOS 7 however, this seems to have no effect. The method does get called, but the return value seems to be ignored by the OS - it auto rotates no matter what.
The documentation does not mention any changes to this method. How can I achieve the desired effect on iOS 7?
Edit: the view controller is being presented (not pushed!) by a UINavigationViewController
:
[self.navigationController presentViewController:vc animated:YES completion:nil];
Solution:
As odd as it may seem, but this solution was not published in the numerous existing questions on this topic. On iOS 7 it seems the answer the UINavigationController
gives to
shouldAutorotate
is what the OS acts on. We need to subclass UINavigationController
to modify its behaviour.
When dealing with a regular navigation stack it is indeed sufficient to just use [self.topViewController shouldAutorotate]
, but when there is modal view, it resides in self.presentedViewController
, not self.topViewController
. Thus the full solution looks like:
- (BOOL)shouldAutorotate {
UIViewController *vc;
if (self.presentedViewController) vc = self.presentedViewController;
else vc = [self topViewController];
return [vc shouldAutorotate];
}
So I just tried you code and it worked which leads me to believe that you are presenting your UIViewController
in a UINavigationController
. For whatever reason, iOS 7 changed how UINavigationController
handle rotations.
The easiest solution is to create a subclass of UINavigationController
that overrides the shouldAutorotate
method and returns the value from the topViewController.
@interface CustomNavigationController : UINavigationController
@end
@implementation CustomNavigationController
- (BOOL)shouldAutorotate
{
return [[self topViewController] shouldAutorotate];
}
@end
So instead of doing this, where viewController
is your object that return NO
for shouldAutorotate
.
UINavigaitonController *navController = [UINavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:navController animated:YES completion:nil];
You would use the CustomNavigationController instead
CustomNavigationController *customNavController = [CustomNavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:customNavController animated:YES completion:nil];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With