I have few view controllers that i present modally using presentViewController:animated: method. I want not to allow the application to rotate while presenting them on iPad since they all have blurred background using FXBlurView which is a mess to rotate and also because sometimes rotating the presented view mess up the presenting one.
I need to support iOS6, 7 and 8 and could not find any solution beside the private API setOrientation: method.
The only solution I found is to create a navigation controller subclass and containing the modal view controller in this navigation controller.
Meaning that you will have to present the navigation controller that will have a root view controller that you originally wanted to present.
Here is a sample implementation for the non rotating (portrait) navigation controller:
@implementation NonRotatingNavigationController
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
@end
You might also "ask" the displayed view controller rather than deciding which orientation is supported.
Like this:
@implementation NonRotatingNavigationController
- (BOOL)shouldAutorotate {
return [[[self viewControllers] lastObject] shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [[[self viewControllers] lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[[self viewControllers] lastObject] preferredInterfaceOrientationForPresentation];
}
@end
Another solution is to add a separate window that will contain the view controller.
This time you will have to implement the rotation methods inside the view controller itself and set it as the root view controller of the new window.
Here is the window creation code (important that the window will be owned by someone - e.g. strong property in the originating view controller - otherwise it will be released and you will see nothing):
@interface ViewController ()
@property (nonatomic, strong) UIWindow *modalWindow;
@end
@implementation ViewController
- (IBAction)buttonTapped:(id)sender {
NonRotatingViewController *vc = [[self storyboard] instantiateViewControllerWithIdentifier:@"NonRotatingViewController"];
UIWindow *modalWindow = [[UIWindow alloc] initWithFrame:self.view.window.frame];
modalWindow.windowLevel = UIWindowLevelAlert;
modalWindow.backgroundColor = [UIColor clearColor];
[modalWindow setRootViewController:vc];
[modalWindow makeKeyAndVisible];
self.modalWindow = modalWindow;
}
@end