ios 6 orientation methods - iphone

the orientation methods have changed in iOS 6.
my whole app in portrait mode got to many view controllers (not tab bar view controllers) i just want to rotate one of my view controller to landscape mode (it actually displays a webView) when i rotate the device.the below method was working in xcode 4.4 but, it's not in Xcode.4.5
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight );
the above method won't work in xcode 4.5 for this reason i have changed the below method but even though its not working....plz any suggestions thanks.
- (BOOL) shouldAutorotate{
[[UIApplication sharedApplication] setStatusBarOrientation: UIInterfaceOrientationPortrait];
return self.modalViewController.shouldAutorotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}

Do you use tab bar view controller? If you use it, then all view controllers in all tabs should be able to rotate even if you only want to rotate only one.
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
This should work fine in iOS6.
If you use UINavigationViewController, then its methods would be called. There is another solution.
// App delegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
And then in view controllers
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Related

First UIView in Portrait orientation and second in Landscape

I have an app which has 2 view controllers. The first viewcontroller should be in portrait and it's ok, but when I'm loading the second view controller, I could not make the app orientation to be landscape... The problem is with iOS 6.
I have tried everything I found on SO.
Using [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; on viewWillAppear and viewDidLoad,
and also:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
} else {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
-(NSInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
Add these code in 2nd View Controller's viewDidLoad method to transform view into landscape :
[self rotateController:self degrees:-90];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];
//set it according to 3.5 and 4.0 inch screen in landscape mode
[self.view setBounds:CGRectMake(0, 0, 480, 320)];
add rotateController method :
-(void) rotateController:(UIViewController *)controller degrees:(NSInteger)aDgrees
{
UIScreen *screen = [UIScreen mainScreen];
if(aDgrees>0)
controller.view.bounds = CGRectMake(0, 0, screen.bounds.size.height, screen.bounds.size.width);
else
{
controller.view.bounds = CGRectMake(0, 0, screen.bounds.size.width, screen.bounds.size.height);
}
controller.view.transform = CGAffineTransformConcat(controller.view.transform, CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(aDgrees)));
}
Now in viewWillDisappear's method to transform view into protrait . Add these:
[self rotateController:self degrees:90];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
//set it according to 3.5 and 4.0 inch screen in protrait mode
[self.view setBounds:CGRectMake(0, 0, 320, 480)];
Also your orientation methods should be like these if not added add these :
- (BOOL)shouldAutorotate
{
//make view landscape on start
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
EDIT : Add these macro for radian
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
you may add this code on this view controller where you want to fix your orientation
Code as Below
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
{
return UIInterfaceOrientationMaskPortrait;
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
{
return (toInterfaceOrientation==UIInterfaceOrientationPortrait);
}
}
and second view controller you may want to rotate all orientation then not necessary to adding any code ios6 will manage the orientation automatically.
You need to select the landscape mode in application summary-> deployment info.
Also if you are using xib file to design the UI, you need to set the orientation of second view controller to landscape
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
-(NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
You were not returning the NO in the method shouldAutorotate , replace you existing code with this .
Hope it will help you.
Prior to iOS 6 i.e in iOS 5 and earlier, an app and a view controller’s rotation is controlled by the individual viewcontrollers while in iOS 6 and later, the view controllers responsible for rotation are the container Viewcontrollers such as UINavigationController & UITabBarController . What are you using as the rootviewcontroller in your project??
Autorotation is clearly explained here in this post- Autorotation in iOS

Alternate landscape triggered at unwanted view

I have a view controller that contains an image and a tableview. From this view controller I connected a segue to a landscape view that contains the image in full screen (same idea used when you turn sideways the Stocks app from Apple to see the graph in full screen).
This segue is called by the following method:
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self performSegueWithIdentifier: #"toGraph" sender: self];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Besides this, when the iphone is at portrait orientation, I can also drill-down the tableview a couple more levels. The problem is the following: at those consequent levels, the segue to the landscape view still gets triggered when I turn the orientation to landscape!... what can I do so that this does not happen? I am only interested in going to landscape mode from the first view which contains the image.
Thank You in advance!
I don't know for sure if I got your issue right.. but if you mean with "drill-down the table view" to go deeper in a navigation controller hierachy, you can try the following..
That's what I did in a (I think) similar situation:
AppDelegate:
in .h:
#property (nonatomic) BOOL shouldAutorotate;
in .m:
// in didFinishLaunchingWithOptions:
self.shouldAutorotate = NO;
// still in .m file
// Autorotation handling
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return self.shouldAutorotate ?
UIInterfaceOrientationMaskAllButUpsideDown :
UIInterfaceOrientationMaskPortrait;
}
Navigation Controller presenting Portrait Controller
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations
{
if (self.selectedViewController)
return [self.selectedViewController supportedInterfaceOrientations];
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate
{
return YES;
}
Portrait View Controller (here's also a very similar segue handling that you have):
in viewWillAppear:
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setShouldAutorotate:YES];
rotation handling:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Landscape View Controller (probably your full screen image):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Deeper in the navigation controller hierachy (where only portrait is wanted):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Looks somehow complicated, but that was the only way, I managed to get those rotation things working properly in both iOS5 and 6.

iPhone interface orientation change not returning to portrait orientation

So I have a view that I present modally when the interface orientation changes to landscape. However when the orientation returns to portrait and the modal view dismisses itself, the tableview from the initial view remains in landscape orientation (this table view must be only in portrait orientation)
Here is the code :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight) );
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
[self performSegueWithIdentifier:#"showCatChart" sender:self];
}
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self refreshTableView];
}
}
I tried to refresh the tableview but that doesn't make it portrait again ...
this could be from the view hierachy ...
NavigationController->tableView (only portrait)->tableview->landscapeViewModalController
With iOS 6, you need to implement the following:
- (BOOL)shouldAutoRotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
In your AppDelegate, you need to change the following:
[self.window addSubview:viewController.view];
to
[self.window setRootViewController:viewController];
Also, keep your current code if you want to support previous versions of iOS.
Use the following in appdelegate.
[self.window addsubview:viewcontroller];
This alone will solve your orientation problem.

Make a UiViewController stay in portrait mode iOS6 VS iOS5

I'm building an app for iOS5 and iOS6. I have this UIViewController inside a UINavigationController and I want it to stay in portrait mode.
The code works for iOS5, but not in iOS6.
// iOS5 rotation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (interfaceOrientation == UIInterfaceOrientationPortrait)
return YES;
else
return NO;
}
// iOS6 rotation
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
What's the problem here??? On SO I've found lot's of similar questions, but generally the answers are not working for me.
EDIT:
Maybe I was not precise, but I need a SINGLE view controller (the homepage of my app) to stay in portrait mode and not all the app.
First of all, A lot depends on with which controller is your UIViewController embedded in.
Eg, If its inside UINavigationController, then you might need to subclass that UINavigationController to override orientation methods like this.
subclassed UINavigationController (the top viewcontroller of the hierarchy will take control of the orientation.) needs to be set it as self.window.rootViewController.
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
From iOS 6, it is given that UINavigationController won't ask its UIVIewControllers for orientation support. Hence we would need to subclass it.
MOREOVER
Then, For UIViewControllers, in which you need only PORTRAIT mode, write these functions
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
For UIViewControllers, which require LANDSCAPE too, change masking to All.
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskAllButUpsideDown);
//OR return (UIInterfaceOrientationMaskAll);
}
Now, if you want to do some changes when Orientation changes, then use this function.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
VERY IMPORTANT
in AppDelegate, write this. THIS IS VERY IMP.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return (UIInterfaceOrientationMaskAll);
}
If you want to provide only Portrait mode for all your viewcontrollers, then apply the portait mask. i.e UIInterfaceOrientationMaskPortrait
Otherwise, if you want that some UIViewControllers stay in Portrait while others support all orientations, then apply an ALL Mask. i.e UIInterfaceOrientationMaskAll
Try out this :
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
UIInterfaceOrientationMask orientationMask = UIInterfaceOrientationMaskPortrait;
return orientationMask;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
This should work in order to support the portrait mode only.

iOS Rotate View Only One View Controller's View

I have two view controllers in a single project. However, I want one of the view controller's to autorotate, and the other to not.
If I set the master project setting as seen below:
Then, all view controllers autorotate, regardless of the following code in the view controller I do NOT want to autorotate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
return YES;
}
return NO;
}
However, if I set the master project settings as seen below, the view controller that I do not want to autorotate does not, but that also means neither can the one that I DO want to.
How must I integrate the master project (plist file) settings with those of the view controllers so that one view controller will auto-rotate while the other will not?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
was depreciated in iOS 6 so if that's what your project is running, that's why it's not working. What you need to do is implement:
- (NSUInteger)supportedInterfaceOrientations
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
The first one will tell the controller what orientation(s) it is allowed to use, and the second will tell it which one to use first. Note that the first method is only called if the method shouldAutorotate: returns YES.
These are the constants you can use for supportedInterfaceOrientations:
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskLandscape
UIInterfaceOrientationMaskAll
UIInterfaceOrientationMaskAllButUpsideDown
Note that these only work on iOS 6.0.
Assume I am using tabbarController & iOS<6.0 try to use the following code solve your issue:
//In First View Controller
//BOOL activeStatus;
-(void)viewWillAppear:(BOOL)animated
{
activeStatus=YES;
}
-(void)viewWillDisappear:(BOOL)animated
{
activeStatus=NO;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) && activeStatus==YES)
{
return YES;
}
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
//In Second View Controller
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}