ios- view controller doesn't load in current orientation - ios

I'm using a subclass of UINavigationController to manage rotations for my app.
#implementation rotatingNavigationController
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
In my first view I only allow portrait orientation:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
I push to a new view controller using a push segue created in the storyboard. The new view controller supports all interface orientations:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
The new view controller ALWAYS loads in portrait, no matter what orientation the device is held in. If I physically turn the device to portrait mode and back to landscape after the view loads, it rotates correctly. How can I correct this, I need the view to load in whatever orientation the device is held in when the view loads?

When you are push the newcontroller. check the interfaceorientation of statusbar then:
-(BOOL)shouldAutorotate
{
if(isPushingViewVC)
return NO
return YES;
}
And
- (NSUInteger)supportedInterfaceOrientations
{
if(isPushingViewVC)
{
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIInterfaceOrientationLandscapeLeft:
return UIInterfaceOrientationMaskLandscapeLeft;
break;
case UIInterfaceOrientationPortrait:
return UIInterfaceOrientationMaskPortrait;
break;
case UIInterfaceOrientationPortraitUpsideDown:
return UIInterfaceOrientationMaskPortraitUpsideDown;
break;
default:
return UIInterfaceOrientationMaskLandscape;
break;
}
}
return UIInterfaceOrientationMaskAll;
}

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;
}

How to lock device orientation in iOS 7 and iOS 8

I have a problem with my app. I cannot lock the orientation of my app. All I need to do is to lock one view controller to landscape mode and the rest are portrait.
This is hierarchy of my app.
*Navigation Controller
*TabBarController
*ViewControllers
You only have to return NO from shouldAutorotate and the landscape orientation from supportedInterfaceOrientation in the one you want to be in landscape.
On the other, return NO too from shouldAutorotate method and portrait orientations mask from supportedInterfaceOrientation.
In all the viewControllers :
-(BOOL)shouldAutorotate {
return NO;
}
In the one you want in landscape :
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
In the controllers you want in portrait :
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
Use below 2 this methods to lock device orientation to landscape.
- (NSUInteger)supportedInterfaceOrientations{
[super supportedInterfaceOrientations];
return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight)
{
return YES;
}
// Return YES for supported orientations
return NO;
}
With NavigationController
-(BOOL)shouldAutorotate
-(NSUInteger)supportedInterfaceOrientations
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
these method are never called , if you use 'show segue(push)'.
change segue 'showDetail' instead 'show'

Disable UITableViewcontroller from rotating in Landscape (keep it Portrait)

I'm trying to keep UITableViewcontroller in Portrait orientation. Hence, I don't want to rotate to Landscape mode. I added below method. But it didn't help, notice I'm using iOS 8:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if(interfaceOrientation== UIInterfaceOrientationPortrait)
{
return YES;
}else
{
return NO;
}
}
Notice: I'm calling the UITableView through UINavigationController
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:svc];
// configure the new view controller explicitly here.
[self presentViewController:navigationController animated:YES completion: nil];
shouldAutorotateToInterfaceOrientation: has been deprecated since iOS 6.0. You should be using supportedInterfaceOrientations and shouldAutorotate.
Here's how you do it:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
EDIT - for UINavigationController
This is one possible way to do it:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
if ([self.visibleViewController isKindOfClass:[UITableViewController class]])
return UIInterfaceOrientationPortrait;
else
return [super preferredInterfaceOrientationForPresentation];
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([self.visibleViewController isKindOfClass:[UITableViewController class]])
return UIInterfaceOrientationMaskPortrait;
else
return [super supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
if ([self.visibleViewController isKindOfClass:[UITableViewController class]])
return NO;
else
return [super shouldAutorotate];
}
Note that you can't force the device orientation, so if the app is in landscape and you then push the table view controller, it will still be in landscape. There are a number of ways to handle this:
Block the user from opening the table view controller by displaying an alert asking them to rotate the device first.
Hide the table view and show a label with a message (or some other indicator) to tell the user to rotate their device.
Handle both orientations.
shouldAutorotateToInterfaceOrientation: is depricated. Instead, use:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}

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)

IOS view controller orientation

I have parent view controller and another modal view controller.
I presented modal view controller within parent's context:
readingViewController * reading_view_controller = [[readingViewController alloc] initWithNibName:#"readingViewController" bundle:nil];
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
[self presentModalViewController:reading_view_controller animated:YES];
Parent viewController will not orient Landscape; so, i added these methods in the parent viewController:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortraitUpsideDown|UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
The presented viewController (modally presented) should orient to all possible orientations; so, i added these methods:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return YES;
}
But, because I assumed (UIModalPresentationCurrentContext), the presented viewController doesn't orient in IOS 6.0 while it is working as expected in IOS 5.0
How to solve this problem please?
If you have a tab-based app, then first add some code in app delegate and also self.window.rootviewcontroller-self.tabbarcontroller.
#implementation UITabBarController (SK8FASTR2App)
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
// your custom logic for rotation of selected tab
if (self.selectedIndex==3){
return UIInterfaceOrientationMaskPortrait;
}
else {
UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown|UIInterfaceOrientationLandscapeLeft|UIInterfaceOrientationLandscapeRight;
return UIInterfaceOrientationMaskAll;
}
}
#end
before
#implementation AppDelegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
Change orientation on that class
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
You should implement
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
eg :-
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskAll;
}

Resources