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!
Related
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;
}
i'm in really bad situation, i have to submit my app, but i have discovered one problem :
My app is a Nav based app, in this app i want only one controller to be able to landscape :
--> Root Controller --> WelcomeController --> LandscapeController
In the landscape controller i have set two views inside the main view, one is portrait mode to tell the user he has to turn the device, the other is set to landscape (in the main view which is in portrait mode)
I have subclassed my navigation controller : MyNavController in which i have set :
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
So the controller on top of the hierarchy decide if the navController can rotate or no.
in my app delegate i have set :
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return (UIInterfaceOrientationMaskAll);
}
so i can have both orientation on my app.
In the Welcome Controller i have set :
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
//return (UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return YES;
}
Which means the Welcome Controller can only be in portrait mode.
In the Landscape Controller i have set :
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
- (BOOL)shouldAutorotate
{
return YES;
}
so that the landscape Controller can rotate.
I call Landscape controller using :
LandscapeController *aLandscapeController = [LandscapeController] allo] init....
[self.navigationController pushViewController:aLandscapeController animated:YES];
It works, but sometimes believe me or not, when i push the landscape Controller and that i turn the device, it is the Welcome Controller which become landscape and take only half of the screen because it can't be in landscape and this so bad to me you can't imagine.
What can i do to avoid that ?
i'll take any help, i'll make donation if i have to.
Thank you very much.
Second sentence of the UINavigationController documentation: "This class is not intended for subclassing." Have you tried it without your override to the navigation controller's orientation behavior? Maybe the navigation controller does the right thing by default, which is to query the child controllers to determine what the orientation should be. But by overriding it, you are breaking the correct behavior, which is more complex than you expected during view transitions.
Keep everything the same except use a standard UINavigationController instead of your subclass. Or if your subclass can't be removed for other reasons, for a quick test try commenting out this code:
/*- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}*/
But you can't rely on anything working right if you subclass a class that the documentation says you shouldn't.
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
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];
}
I am working on an app (my first one), which is basically a TabBar app.
To be more precise there are:
- a login view controller
- a tab bar controller (when login is done)
- a landscape view controller that is used when the first itel of the TabBar is switch from Portrait to Landscape.
So, when I am in the first tab, I need to be able to move to landscape view to display some other data. In my tab bar controller, I have implemented those methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if([self selectedIndex] == 0)
return YES;
return NO;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Get AppDelegate
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
// Remove TabBarView and add graph Landscape View
[self.view removeFromSuperview];
[delegate setSubViewLandscapeViewController];
}
}
In the delegate, I have implemented the setSubViewLandscapeViewController and the setSubViewTabBarController:
- (void)setSubViewTabBarViewController {
[window addSubview:[tabBarController view]];
}
- (void)setSubViewGraphLandscapeViewController {
[window addSubview:[landscapeViewController view]];
}
I want the landscapeViewController to display only in landscape mode, I have then (in my landscapeViewController):
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
NSLog(#"willRotateToInterfaceOrientation");
}
A part of this works fine, I mean the switch from portrait to landscape is ok (when I am in the first tab), the tabbarcontroller is remove from the SuperView and the landscape view is added as a subview instead.
The thing is... I do not know how to switch back to portrait mode (and then load the previous controller, the tabBar one using the setSubViewTabBarViewController of my delegate). It seems none of the willRotateToOrientation, willRotateFromOrientation, .. are triggered when I actually move the device from the landscape view...
In short, when I am in the landscape view I do not know what to do to move back to the tabbar view... I am kind of stuck in the landscape view once I am in this one.
Thanks a lot for your help,
Luc
Look at the pie chart in CPTestApp-iPhone in the examples folder. It handles rotation by implementing -(void)didRotateFromInterfaceOrientation: and resizing the graph after a rotation.
Well, I managed to get a solution for this problem.
In fact, while moving from portrait to landscape I removed the tabbarcontroller from window subview and add the landscapeviewcontroller instead.
It seems it was not the correct thing to do.
Instead, I add the landscapeViewController as subview of the tabbarcontroller and remove it when going from landscape to portrait.
I still have a problem however with the y position of the landscape view which seems to changes when I do several decive rotation in a row....
Regards,
Luc