iOS: Parent/Children View Controllers and autorotation - ios5

I am really trying to understand how the autorotation works in iOS5 and iOS6 with parent and children View Controller.
Let's say I have a RootViewController with three UIViewControllers
The Root View Controller has the three view controllers as Children View Controllers, and is responsible of swapping them UIViewControllers.
Now, I want one of the children view controller to be able to autorotate in all interface orientations, and the other two only Portrait Interface Orientation.
Is this possible? How is it done in iOS 5? And iOS 6?
I am really trying to understand all the shouldAutorotateToInterfaceOrientation: supportedInterfaceOrientations preferredInterfaceOrientationForPresentation shouldAutorotate shouldAutomaticallyForwardRotationMethods methods. But I can't get this to work :\ ........

For those two views (which you want to be available only in portrait mode):
Open their View Controllers, and implement this method:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return UIInterfaceOrientationIsPortrait(toInterfaceOrientation); // don't rotate if it's not portrait.
// if you don't want the upside down portrait mode to be available as well, return the expression from below
// return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
This one is actually deprecated, so you also may want to use this:
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
// if you want it to be also in upside down portrait mode, return the expression below
return UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown;
}

Related

How stop device Orientation into Landscape Mode in UIViewController With UINavigationBarController and UITabbarController

How to stop device Orientation into Landscape Mode in UIViewController With UINavigationBarController + UITabbarController.
Its up to individual view controllers to decide if they'd like to auto-rotate. Container view controllers (like UINavigationController, tab-bar controller or one of your own) typically delegate to their children to decide this. Add/override these methods on your view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return NO;
}
- (BOOL)shouldAutorotate
{
return NO;
}
One is the older style and one is the iOS6+ style.
if you want to competently remove orientations for your app in xcode you can set supported orientations

View Controller: Ladnscape to Portrait

I have a view controller in my app. Let its first view controller, my first view controller appears in portrait mode in phone, when user rotate phone in landscape mode, first view controller also rotate in landscape mode.
Its working fine, and now I have a button on first view controller, when I touch the button second view controller appears. I just want to do is that the second view controller should always appear in portrait mode, even though the first view controller is in landscape mode.
Is there any methods which I have to override to get this functionality?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In second view controller keep this.
In a navigation controller, the orientation of your controller depend on the orientation of the navigation controllerĀ“s root controller.
You have two possibilities:
make your root controller's shouldAutorotateToInterfaceOrientation: return different values depending on which controller is actually shown;
use a transform on you your view controller's view so that it is rotated.
I would give a try to the first way, to start. Have a look at this post for an idea how to do it (just ignore the UITabBarController stuff), or try this (which simply relays the message to the top controller in your navigation hierarchy):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [self.navigationController.topController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
In order to achieve the same result on iOS6, try and define the following methods:
-(NSUInteger)supportedInterfaceOrientations {
return [self.navigationController.topController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.navigationController.topController preferredInterfaceOrientationForPresentation];
}

iPhone iOS 6 UITabBarController Portrait Only, How to have Modal View Controller support Landscape Orientation

What I'm trying to do is the simplest concept. But, I'm just not getting any desired results.
My app is a standard Tab Bar app, all of the view controllers in each of the tabs support Portrait orientation only, which is exactly what I want.
However, in one section of the app, I display a modal view controller, which obviously covers the tab bar controller. It is a text input screen, and I would very much like this view to be able to support Landscape orientation as well as portrait. Then, once the user cancels out of that modal view controller, the tab bar controller would be displayed again, everything in portrait.
I have tried so many things, and nothing works. If I tell the app to support both orientations, then the rotations occur correctly on the modal, but also on the rest of the app, which I do not want.
I have tried implementing all the new shouldAutorotate and supportInterfaceOrientations methods, and nothing ever seems to work.
The closest attempt I had to almost working, was I created a UITabBarController category in my app delegate, to fowarded the shouldAutorotate and supportedInterfaceOrientations. This seemed to work initially, but for some reason, whenever cancelling out of my modal vc, my tab bar portion of the app was always shifted up by 20 pixels up behind the status bar?? I have no idea what that's all about.
I created a test app, in which there is no UITabBarController, and I was able to code my desired behavior with no problem, and it works perfectly. So, clearly something with regard to Tab Bar Controller is making this a difficult issue.
Please let me know what the trick is in solving this simple concept.
Thanks!
I was able to solve this by creating a couple of categories for UITabBarController and UINavigationController. Here is the code I used:
#implementation UITabBarController (rotations)
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
#end
#implementation UINavigationController (navrotations)
- (BOOL)shouldAutorotate {
return [self.topViewController shouldAutorotate];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [self.topViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
#end
Then, of course each view controller I display would simple need to respond to the shouldAutorotate and supportedInterfaceOrientations methods.
Apparently in ios6 and above, the way rotation works is different. So what you have to do is the following
In your .plist support all 4 orientations.
Subclass the UITabBarController (for e.g: CustomTabBarController)
In the CustomTabBarController put the following lines of code
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
In your app delegate or where ever you are initializing UITabBarController, replace those instances with CustomTabBarController instances.
In your modal controller put the lines
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
-(BOOL)shouldAutorotate{
return NO;
}
And it should all work.
Apparently the trick, I found is that, UITabBarController will not listen to your instructions. It will support all the orientations you mention in the .plist.
There fore you have to subclass it.
I tried doing all of the above and it works fine. Do let me know and I can send you the code if you want.

Stop a modal UIViewController from rotating

The modal UIViewController's parent auto-rotates, but when the modal VC is up I only want it to appear in portrait and not be rotatable. I have tried simply returning NO from shouldAutorotate... in the modal VC, but no joy. Supporting iOS 5+.
Any help greatly appreciated.
Basically, if you presenting Modal Controller on Any Container Controllers (i.e. UINavigationController) it have autorotation method return YES by default. So you have to make subclass for your UINavigation Controller and Deprecate Autorotation there.
For iOS 5 use method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait) : self.enableRotations;
}
for iOS 6:
- (NSUInteger)supportedInterfaceOrientations {
switch ([UIDevice currentDevice].userInterfaceIdiom) {
case UIUserInterfaceIdiomPad: return UIInterfaceOrientationMaskAll;
case UIUserInterfaceIdiomPhone: return UIInterfaceOrientationMaskPortrait;
}
}
- (BOOL)shouldAutorotate {
return NO;
}
It can be doable, but I would think twice before doing that.
As a user;
I launch the app and use in landscape.
trigger an event (eg. press button).
see a view which is portrait.
rotate the phone and look in portrait.
close the modal view.
get landscape view again.
need to rotate the phone again
Bad usability...
you have to present that new controller on a new navigation controller.This will solve your problem

UIInterfaceOrientation within UINavigationController

I would like to control the device reorientation effect on two different UIViewControllers pushed onto a UINavigationController.
On the first view, I am setting my app to rotate to portait only, but seems it its doing it on all views.
This is the code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
And, on another view I am using the following code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
On my second view I would like to rotate to all orientations, only on the first i want the rotation to be restricted to portrait only.
Thanks!