Programmatically Rotate UINavigationController - iphone

I know how to control the autorotation of a UINavigationController, but I would like to programmatically rotate a UINavigationController: the navigation bar, and view stack, to a specified UIInterfaceOrientation value, regardless of the current device orientation.
Is that possible?
Thanks

First, setup your application/view controller to use only one specific orientation (that is, block automatic rotations).
Then you can rotate the underlaying view layer (UIView.layer of type CALayer) using an affine transform.

Implement the - shouldAutorotateToInterfaceOrientation: in your view controllers insided the UINavigationController, only return YES on your desired orientation. e.g., the UINavigationController only display on landscape:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
May this helps.

Related

View is not rotating

I am making a navigation based app and I need only portrait orientation except in a ZoomPictureViewController ( Zoom in, zoom out images) that supports all orientations.
I am presenting ZoomPictureViewController and returning YES in shouldAutorotateToInterfaceOrientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
But I get no rotation. I know that shouldAutorotateToInterfaceOrientation, willRotateToInterfaceOrientation, RotateToInterfaceOrientation are only get called on the current/visible view controller but this is not happening in my case. I have checked it via putting breakpoints and NSLog.
Are you using any type of Navigation Controller or a Tab View Controller? I've noticed that there are issues when rotating a UIView that's not the first or only view as a direct child of the main window.
So if your UIView is part of a Navigation Controller or a Tab View Controller, you'll also need to override shouldAutoRotateToInterfaceOrientation on the Navigation Controller or Tab View Controller.
Also I here's an important gotcha in the Apple documentation that might explain the problem you are having.
Tab bar controllers support a portrait
orientation by default and do not
rotate to a landscape orientation
unless all of the root view
controllers support such an
orientation. When a device orientation
change occurs, the tab bar controller
queries its array of view controllers.
If any one of them does not support
the orientation, the tab bar
controller does not change its
orientation.

Rotate view iPhone tabbar app

I have an app with a mainwindow which contains a tabbar controller and a number of different views. I want the whole thing to be able to rotate in each direction, however doing
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
didn't help, while that did work in other apps.
The UITabBarController requires that you enable rotation on all view controllers it manages. So each view controller should return YES for that method for the orientations you wish to rotate to.
If you wanted each view to rotate, you have to return YES on each view in the tab bar controller as well.

Problems with Interface Orientation and UITabBarController

Quick problem:
I have an UITabBarController with 2 navigation controllers [lets call them Left and Right Controller]
On the default selected Left Controller I can push a new View Controller that detects interface orientation.
On the Right Controller I can push the same View Controller but it won't detect interface orientation, or for that matter, It won't even go into the shouldAutoRotateInterface method at all T___T
Haaalp!!
If it is of any relevance, the View Contoller that I'm pushing use the hidesBottomBarWhenPushed property.
Most likely this is your problem:
Tab bar controllers support a portrait
orientation by default and do not
rotate to a landscape orientation
unless all of the root view controllers support such an orientation.
When a device orientation
change occurs, the tab bar controller
queries its array of view controllers.
If any one of them does not support
the orientation, the tab bar
controller does not change its
orientation.
The solution is to override the following method on every view controller leading to your view:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
return YES;
}
For example, instead using the default UITabBarController in IB, replace it with your own subclass containing just the method above.
I'm a bit late to the party on this, but I ran into a problem with autorotation at startup for a tab bar app I wanted always to run in portrait.
The app's plist has the necessary settings to both start in and only allow portrait mode, and all my view controllers only allow portrait mode. Yet, when I started the app holding my iPhone in landscape, the app started in portrait, but then rotated to landscape!
Rather than subclass UITabBarController, I simply overrode UITabBarController's shouldAutorotateToInterfaceOrientation: method using a category on class UITabBarController. I included this code in my app delegate:
#implementation UITabBarController(UITabBarControllerCategory)
-(BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
{
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Works beautifully, and is quite lightweight.
does your uitabbarcontroller implement the auto rotate? any child viewcontroller that wants to implement autorotate has to have its parent implement autorotate.

Showing a landscape UIViewController in a portrait UITabBarController/UINavigationController

I understand that this question (or variations of it) has been asked quite a few times, however it's still how to best approach this problem without delving into kludgy hacks.
I have an application with the following layout:
UITabBarController
↳ UINavigationController
↳ PortraitViewController
↳ LandscapeViewController
The first PortraitViewController has its rightBarButtonItem set to a UIBarButtonItem, which calls landscapeButtonPressed:. That method pushes the LandscapeViewController onto the view controller stack.
In LandscapeViewController, I set hidesBottomBarWhenPushed to YES during initialisation, since I only want the navigation bar visible.
I also call setStatusBarOrientation:UIInterfaceOrientationLandscapeRight on [UIApplication sharedApplication] in loadView and viewWillAppear:, and then set it back in to UIInterfaceOrientationPortrait in viewWillDisappear:.
In my shouldAutorotateToInterfaceOrientation: implementation, I return YES only for UIInterfaceOrientationLandscapeRight.
The PortraitViewController looks like this:
Portrait View http://img.skitch.com/20091007-18ur7p3iubkrb1if5cak8wdxkb.png
The LandscapeViewController looks like this:
Broken Landscape View http://img.skitch.com/20091007-f3ki1ga5m4ytkyg3wgwektp86e.png
As you can see, the view is not rotating correctly. If I call the private -[UIDevice setOrientation:] method before I call -[UIApplication setStatusBarOrientation:], I can get the navigation bar to rotate properly, but I'd rather not be calling private methods and there doesn't seem to be a way to get the bounds of my main view for laying out subviews. Using the private method results in this:
Better Landscape View http://img.skitch.com/20091007-8ckbx6gpbiateju9qjgew4x3k2.png
Any ideas on how to solve this problem?
My goal is to have a view in landscape orientation, with valid landscape CGRect coordinates that I can use as the basis for laying out subviews.
Nathan,
I feel that you have set PortraitViewController as the rootViewController of UINavigationController. I also believe that you are restricting the PortraitViewController's orientation only to UIInterfaceOrientationPortrait only in the shouldAutorotateToInterfaceOrientation method. If so then, any view controller that you push will have the orientation of the rootViewController itself unless you are not changing the device orientation by rotating your device.
So if you need the LandscapeViewController in the UIInterfaceOrientationLandscapeRight orientation then just allow this in shouldAutorotateToInterfaceOrientation: method and don't screw things by explicitly setting the device orientation.
The LandscapeViewController is not automatically rotating because interfaceOrientation is UIInterfaceOrientationLandscapeRight, so you have to return YES for UIInterfaceOrientationLandscapeRight
To have your views resizing correctly you have to open your xib file with Interface Builder, then into the Inspector and finally into the tab "Size".

mkmapview in landscape mode

Is it possble to show a map in landscape mode?
Yes.
The easiest way to accomplish it is to put your map view in a view controller that you then present in some way. Whatever orientations the view controller then supports will cause the hosted map view to rotate to automatically.
In your view controller you'd implement this method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
That example handles both lanscape orientations. As long as your map view is set to autoresize correctly in your NIB file it should all just work.