ios preferredInterfaceOrientationForPresentation not called - ios

i just create a new single view application,and write three funcs in ViewController.m file.
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
First Question
I expect the Simulator rotate my view,but the view orientation is Portrait. And I find the third func not called in ViewController. why?
Second Question
I read some blogs , they said if shouldAutorotate return NO, the func supportedInterfaceOrientations will not called,but in my test, this func called several times,why?

You have to use a UINavigationController subclass (not sure your using navigation in your project...) and implement those methods in the subclass. Do not forget to set your subclass as view-controller navigation controller
Example for navigation controller subclass:
// add this in your CustomNavigationController.h file
#import <UIKit/UIKit.h>
#interface CustomNavigationController : UINavigationController <UINavigationControllerDelegate>
#end
// add this in your : CustomNavigationController.m file
#import "CustomNavigationController.h"
#interface CustomNavigationController ()
#end
#implementation CustomNavigationController
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.visibleViewController preferredInterfaceOrientationForPresentation];
}
#end

Related

Disable autorotate on a single UIViewController not working in iPad Pro

I want to lock single viewcontroller in iPhone and iPad.
This below code is working perfectly in iPhone 4,5,6 iPad, iPad 2 ,iPad retina.
But not working in iPad pro.
#implementation UINavigationController (Orientation)
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
This above code is written in my view controller which view controller i do not want to rotate.
Write this below code in view controller, which view controller u want to lock in portrait mode
#implementation UINavigationController (Orientation)
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
#pragma mark Orientation
-(BOOL)shouldAutorotate
{
[super shouldAutorotate];
return NO;
}
-(NSUInteger) supportedInterfaceOrientations {
[super supportedInterfaceOrientations];
// Return a bitmask of supported orientations. If you need more,
// use bitwise or (see the commented return).
return UIInterfaceOrientationMaskPortrait;
// return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
[super preferredInterfaceOrientationForPresentation];
// Return the orientation you'd prefer - this is what it launches to. The
// user can still rotate. You don't have to implement this method, in which
// case it launches in the current orientation
return UIInterfaceOrientationPortrait;
}
And now do this below changes in your plist file
Write this in your view controller which you don't want to rotate
This will prevent any rotation.
The view controller class you don't want to rotate should have this.
- (BOOL)shouldAutorotate
{
return NO;
}
The containing navigation controller class should have this.
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutoRotate];
}
This will only rotate to portrait
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

ECSlidingViewController 2.0 disable rotate for one UIViewController

My app build with ECSlidingViewController 2.0 as the sliding menu. I would like to disable the rotate for only one UIViewController . all my UIViewController start with UINavigationController.
I have make a SubClass of UINavigationController to implement the methods and assign the subclass to all UINavigationController in the sotryboard. but it does not work. it seems the code not triggered.
Inside MyNavigationController.m :
#import "MyNavigationController.h"
#import "ContactUsViewController.h"
#interface MyNavigationController ()
#end
#implementation MyNavigationController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate {
NSLog(self.topViewController.description);
if ([self.topViewController isMemberOfClass:[ContactUsViewController class]]){
return NO;
}else{
return YES;
}
}
#end
ContactUsViewController is the UIViewController i don't want to rotate.
5 steps (I am running with Storyboard and IOS 7)
Subclass the ECSlidingViewController. (eg. MyECSlidingViewController)
Create your own shouldAutorotate and supportedInterfaceOrientations in the MyECSlidingViewController.
SubClass the UINavigationController and assign to all your existing UINavigationController. (eg. MyNavigationController)
Create your own shouldAutorotate and supportedInterfaceOrientations in the MyNavigationController.
in the UIViewController you want to set to Portrait only.
MyECSlidingViewController.m
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
MyNavigationController.m
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
YourViewController.m
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Hope it helps !

1st ViewController in Portrait and SecondViewController in Landscape Mode

My requirement is this my 1st viewcontroller open in Portrait mode only.and when user goes to 2nd viewcontroller i want that controller in Landscape mode how may i do this
i tried this code
1st ViewController.m
- (BOOL)shouldAutorotate
{
returnc YES;
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
{
return (interface==UIInterfaceOrientationMaskPortrait);
}
Code for 2nd ViewController.m
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
//return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
this will not working fine for me.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);
}
UPDATED:
You can do this by creating category of UINaviagationController
code for .h file is
#interface UINavigationController (autorotation)
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
and code for .m file is
#implementation UINavigationController (autorotation)
-(BOOL)shouldAutorotate
{
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
[self.topViewController shouldAutorotate];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#end
paste following code in viewcontroller .m file of second view controller (under #implementation section)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Now select the second view controller in storyboard (Selection indicated by blue border around view controller), go to the attribute inspector (right side 'shield' like image) change the orientation to landscape.. That's it.. .Tell me if it doesn't work for u. ..:)
I am solving my problem using Category....
Add new files and select Category and make subclass UINavigationController class.
here is the code for category for .h
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#interface UINavigationController (orientation)
#end
code for .m file
#import "UINavigationController+orientation.h"
#implementation UINavigationController (orientation)
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
if (delegate.islandscape)
{
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
isLandscape is declared in App delegate to check weather First view controller or secondView Controller isLandscape is Bool.
Now FirstViewController.m file i want that in Portarit mode so used this code
- (IBAction)PlayClicked:(id)sender
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
self.navigationController.navigationBarHidden=YES;
delegate.islandscape=YES;
ViewController * v=[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self presentViewController:v animated:NO completion:nil];
//[self dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:v animated:YES];
}
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
and SecondViewController i want that in Landscape mode used this one.
delegate.islandscape=NO; // called transfer to Category
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}

preferredInterfaceOrientationForPresentation not getting called

I have a scenario in which I have a UITabbarController with 5 tabs. Each tab contains a UINavigationController.
Now in one of the UINavigationController rootViewController, when I select an option, another viewcontroller is pushed. Now I want the another view controller to be Landscape only.
Following is the code of my UITabBarController n UINavigationController category for Orientation
#implementation UITabBarController (rotation)
-(BOOL)shouldAutorotate
{
if ([self.selectedViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.selectedViewController shouldAutorotate];
}
else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([self.selectedViewController respondsToSelector:#selector(supportedInterfaceOrientations)]) {
return [self.selectedViewController supportedInterfaceOrientations];
}
else if(DEVICE_IS_IPAD)
return UIInterfaceOrientationMaskAll;
else
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
if ([self.selectedViewController respondsToSelector:#selector(supportedInterfaceOrientations)]) {
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
return 0;
}
#end
#implementation UINavigationController (AutoRotationForwarding)
-(BOOL)shouldAutorotate
{
if ([self.topViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.topViewController shouldAutorotate];
}
else {
return YES;
}
}
-(NSUInteger) supportedInterfaceOrientations {
if([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientations)])
{
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
if ([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientations)]) {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
return UIInterfaceOrientationPortrait | UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationPortraitUpsideDown;
}
#end
and the code for the ViewController which I want to be Landscape only is :
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if(DEVICE_IS_IPAD)
return UIInterfaceOrientationMaskLandscape;
else
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
The Main issue is preferredInterfaceOrientationForPresentation is not at all called for UITabbarController or UINavigationBarController or even the view controller which I want to show.
Could you please let me know what am I doing wrong?
Thanks.
May be you forgot to addsupportedInterfaceOrientationsForWindow to your AppDelegate?
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
Beware of nil. I was following a similar approach of subclassing UINavigationController to relay the rotation messages to the topViewController. It worked great except the time the application launched. When you launch the application there is no topViewController (yet) but the OS needs to determine the supported orientation NOW AND for the the top-most viewController (the UINavigationController). If you fail to to provide an answer at the right time the UINavigationController will appear in the wrong orientation.
Note: PreferredInterfaceOrientationForPresentation is not called for UINavigationController
If your are using a UINavigationController as the root window
controller, it will be its shouldAutorotate &
supportedInterfaceOrientations which would be called.
iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates)

how to force view controller to stay in portrait mode?

I have an iOS application with storyboard. I want my last viewcontroller to stay always in portrait mode. I've been reading and I found that since
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
is deprecated I should use other methods like
-(BOOL)shouldAutorotate
-(NSInteger)supportedInterfaceOrientations
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
but i have tried so many combinations of this methods and I have not been able to do it. So please can someone tell me the correct way?
Since your UIViewController is embedded in a UINavigationController it'll never get called unless you forward on the calls yourself. (A bit of a flaw in UINavigationController in my opinion)
Subclass UINavigationController like this:
#interface RotationAwareNavigationController : UINavigationController
#end
#implementation RotationAwareNavigationController
-(NSUInteger)supportedInterfaceOrientations {
UIViewController *top = self.topViewController;
return top.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate {
UIViewController *top = self.topViewController;
return [top shouldAutorotate];
}
#end
If you have UIViewControllers within other UIViewControllers (ie a UINavigationController or a UITabBarController), you will need to proxy those messages to the child object you're implementing this behavior for.
Have you set a breakpoint in your implementations to be sure your view controller is being queried?
In AppDelegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController) {
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
In Your ViewController:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

Resources