Fixing the orientation of view controllers - iphone

I have a button in my RootViewController ....
when i click on this button it will navigate to some otherViewController.
but i want that when i click on the Button otherViewController's Orientation should be Landscape
& when i back from this page(otherViewController) i should got again Portrait mode.
lots of Thanks for any help.
Plz help me i m new in Iphone so can't able to handle this.

Note in iOS 6 shouldAutorotateToInterfaceOrientation is deprecated. Instead you should use supportedInterfaceOrientations and return a UIInterfaceOrientationMask.
So for example:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
Here are all the UIInterfaceOrientationMask options you might return:
UIInterfaceOrientationMaskAll
UIInterfaceOrientationMaskAllButUpsideDown
UIInterfaceOrientationMaskLandscape
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskPortraitUpsideDown
You should also consider the preferredInterfaceOrientationForPresentation.

In general, orientation should only change from portrait to landscape (or vice versa) when the user rotates the device.
However, if you want your RootViewController to always present its view in portrait and your OtherViewController to always present itvs view in landscape, that's easy enough.
In your RootViewController's .h:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In your OtherViewController's .h:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Although this would probably be better as it would allow both landscape-left and landscape-right rotations:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

The only way I am aware this can be done is by presenting otherViewController modally.
See my answer here: UIViewController loads rotated to landscape but only supports portrait

Maybe it helps.
in viewWillAppear of your new view controller add
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscape]
and in viewWillAppear of your root viewController add
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
It will cause warning but it works.

Related

Keep all views portrait except one

Right I have done a lot of research on this and have hit a block.
I am developing an app which has multiple view controllers. I have the 'homepage', if you will, which all the others views can be access from (this ViewController.m). I also then have a UINavigationController.m attached to the ViewController.m to allow a full navigation bar etc.
My problem is that I am wanting all views to be shown in portrait EXCEPT one view, which I only want in landscape. In my app options, I have set it to enable all orientations and then I was reading that you should override the main orientation in your root view controller (which I assume is the navigation controller?), so I add:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
This overrides everything and only portrait works. I have then tried adding:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
To the view that I want to have in landscape only but it fails to work in the simulator.
Can anyone provide me with a solution? :/
(I would like iOS5 and iOS6 support if possible)
[EDIT]
I should add, I haven't edited AppDelegate in any way.

How to get different autorotation function in different UIViewController in iOS 6 [duplicate]

ADDED:
You can access this project on github
ios6rotations
Sorry guys for asking the question about screen rotation in iOS 6 but this is really a pain in the ass..and I still can't understand it completely - for some reason it behaves differently under certain circumstances.
I have the following simple hierarchy of views in my test app:
What I'm trying to achieve is - to keep blue controller in landscape only and red one is only in portrait.
I have a subclass of UINavigationController with such code inside:
#implementation CustomNavController
- (BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
In my blue controller I implemented this:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
And in red controller this:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Now I have the following behavior:
App started in landscape (OK)
When I press the button my red controller pushed in landscape too (this is not ok because it must be shown in Portrait)
It successfully rotates to portrait but not backward to landscape
If I leave the red controller in Portrait mode my blue controller (which is restricted to landscape) shows in Portrait mode.
P.S.
All my rotation methods(posted above) are getting called normally.(by the way why do these methods getting called so many times per screen transition - 5-6 times)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation does not getting called with pushing
All(except portraitUpsideDown) orientations are included in plist.
The question is - how to force rotation to supported orientation in each controller?
I suggest you to post here (as answers) any 100% working code to handle rotations in ios6 (for example if you have some for iPad with SplitController) - I'll keep this question in favorites to have all in one place when I need to handle some specific situations. Cheers!
ADDED:
Please do not post this as answer from landscape to portrait I hope that there'
s more elegant way to do it.
Using -[UIDevice setOrientation:] is a private API, and will get your application rejected. See this question.
What you ask is not possible using public API and is also not recommended from HIG standpoint. What is supported and you should implement, is modal presentation of the different view controllers with different supported interface orientation. This is why the default implementation of UINavigationController is to always rotate; it assumes all view controllers have the same supported interface orientations.
Take for example video playback on iPhone. Open the video apps (that comes with iOS). The root view controller only supports portrait orientation. However, start a video, and a modal view controller pops up which only supports landscape interface orientations. This seems exactly the behavior you wish to achieve.
This is why preferredInterfaceOrientationForPresentation is not called. preferredInterfaceOrientationForPresentation only gets called when using presentViewController:animated:.
A small gotcha, if you require a navigation bar in each stage of your scene, you will need to enclose each modal view controller with a navigation controller. You can then pass the required data in prepareForSegue: by accessing topViewController of the navigation controller object in the segue.
Here is an example project which behaves correctly according to your requirements (or at least will give you ideas how to implement):
http://www.mediafire.com/?zw3qesn8w4v66hy
My two cents worth.
You can present an empty transparent modal view quickly then dismiss it, maybe on ViewDidLoad: or viewWillAppear: on your ViewController and ViewControllerSecond class as a quick workaround.
Also, in storyboard, you can set ViewController class orientation to landscape visually.
use this line for programmatically change orientation... work 100%
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
and also when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file.. at the top.
#interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
and after that in bellow method just write this code if required..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return your supported orientations
if (currentMainView==blueOne) {
return toInterfaceOrientation== UIInterfaceOrientationPortrait;
}
}
I have a similar situation in one of my apps (although do note that I am not using UINavigationController).
Change the shouldAutorotate methods in both of your viewControllers:
//in blue (landscape only)
-(BOOL)shouldAutorotate{
if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
return YES;
}
else {
return NO;
}
}
//in red (portrait only)
-(BOOL)shouldAutorotate{
if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
//note that UIInterfaceOrientationIsPortrait(self.interfaceOrientation) will return yes for UIInterfaceOrientationPortraitUpsideDown
return YES;
}
else {
return NO;
}
}
Keep the supportedInterfaceOrientations methods the same.
#pragma mark- Orientation Delegate Method:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{ Orientation = [UIApplication sharedApplication].statusBarOrientation;
if (Orientation == UIInterfaceOrientationLandscapeLeft || Orientation == UIInterfaceOrientationLandscapeRight)
{
// self.scrollView.contentOffset = CGPointMake(self.view.bounds.size.width,1200);
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(768, 2150)];
}else if (Orientation == UIInterfaceOrientationPortrait || Orientation == UIInterfaceOrientationPortraitUpsideDown)
{
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(768, 1750)];
}
}
In order to use navigation with orientation together, you should take a bunch of viewcontrollers like an array.
After that checkout following methods,
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
this changes in your methods will help you a lot.
Enjoy Programming!

iOS 6 auto rotation issue - supportedInterfaceOrientations return value not respected

I've got an app where I have a UINavigationController subclass as my rootViewController. I've got a UITableViewController that lets the user edit some settings, it should always be in portrait mode. My app also needs to support all other orientations after I push a MoviePlayer component onto the navigation controller.
The UITableViewController subclass has this implementation of supportedInterfaceOrientations:
- (NSUInteger)supportedInterfaceOrientations {
LLog();
return UIInterfaceOrientationMaskPortrait;
}
The logging command tells me that this gets actually called.
The problem is that the return value is not respected, i.e. the screen turns to landscape orientation when I turn the device.
What can I do to make the settings view always show in portrait but allow orientation changes for the video viewer?
More information: my UINavigationController subclass doesn't override shouldAutorotate or supportedInterfaceOrientations. I haven't implemented
- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
method in my AppDelegate and I have enabled all orientations in the target summary.
I had issue that some ViewControllers in the navigation stack support all the orientations, some only portrait, but UINavigation controller was returning all app supported orientations, this little hack helped me.
#implementation UINavigationController (iOS6OrientationFix)
-(NSUInteger) supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
#end
You also need to add:
- (BOOL)shouldAutorotate {
return NO;
}
and set the supported rotations for the root view controller in the app plist file to only portrait.
Category for UINavigationController not working for me. I don't know why. I solve my problem with such category of UIViewController:
#implementation UIViewController (Orientation)
- (BOOL) shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if ([self isKindOfClass:[PlayerViewController class]])
{
orientations |= UIInterfaceOrientationMaskLandscapeLeft;
orientations |= UIInterfaceOrientationMaskLandscapeRight;
}
return orientations;
}
#end

How to disable portrait orientation on UINavigationController rootViewController

I have a class, HomeView, as the rootViewController of a UINavigationController on my iPad application. Only landscape orientation is set in the info.plist file and HomeView does not implement shouldRotateToInterfaceOrientation:, however the view is rotating for both orientations while the simulator is rotating.
How do I only use the landscape orientations in my UIViewController?
If you do not implement shouldAutorotateToInterfaceOrientation: the runtime will call the method on the Super class, UIViewController.
Instead you should respond appropriately to the method with the orientations you want to rotate to:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
BOOL shouldAutorotate = NO;
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
shouldAutorotate = YES;
}
return shouldAutorotate;
}
Take a look at the UIInterfaceOrientation reference page and the UIViewController's shouldAutorotateToInterfaceOrientation: reference page for more information.
You shouldn't remove the shouldAutorotateToInterfaceOrientation method; that will not stop the interface from rotating, it will only not execute any code that you could have in that method. You should instead try something like this (assuming that you don't ever want the interface to rotate):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return NO;
}

Xcode can't change back to landscape from portrait automatically

I have an iPhone app in which the RootViewController instance starts out in the landscape mode. It supports camera so it changes to portrait mode to take a photo. Once done it comes back to the RootViewController instance but the orientation doesn't change to landscape. I want this to automatically shift to the landscape orientation.
I tried adding
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]
in viewWillAppear method of RootViewController or viewWillDisapper of CameraViewController but orientation doesn't change. How do I programmatically change the orientation?
Try implementing following method in your controller.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight))
return YES;
return NO;
}
Hope it helps.