How to control the page orientations in your iOS PhoneGap application part 2

Sunday, July 29, 2012 by David Conlisk

UPDATE: A number of commenters tell me that this doesn't work with iOS 6 or Cordova 2.1. This was developed using iOS5 and Cordova 2.0. If anyone finds a way to make it work for the latest versions please let me know in the comments!

Okay so you've read my previous blog post about page orientation in your PhoneGap application (of course) but you realise, like I did, that although you've managed to prevent the device from going into landscape mode on certain pages in your app, it's still not a flawless solution. Users can still go to, for example, the graph page, flip their phone into landscape, then browse back to your home page et voila - it's being displayed in landscape! So how to prevent this?

Please note that I'm assuming you're using PhoneGap (Cordova) v2.0.0 here.

This part is a bit trickier and I had to hack the existing PhoneGap Orientation plugin to get this to work. I've simplified it slightly. You just need to add the Orientation class (see below for the code) to your project, then call it from javascript to force the rotation of the screen when your page changes in your PhoneGap application. So in my case, for every screen except the graph screen, I would call to the plugin to rotate to portrait orientation. This way if a user was in landscape orientation when viewing the graph screen, and was holding the phone in landscape orientation, and clicked the home link, the orientation would switch back to portrait (because of my javascript call).

I've included my code below.

1. I added Orientation.h and Orientation.m into the Plugins folder in my PhoneGap 2.0 project.

2. I updated the Cordova.plist file and added a new entry in the Plugins section, key "orientation" and value "Orientation".

3. Then in my javascript I did this when loading a page, to force all pages except my graph page into portrait orientation:

// If we're on the graph page, then ensure content rotates to current physical device orientation
        if (viewname == "graph") {
            switch(window.orientation) 
            {  
                case -90:
                    options = [{landscapeleft:true}];
                    break;
                case 90:
                    options = [{landscaperight:true}];
                    break;
                case 180:
                    options = [{portraitdown:true}];
                    break;
                default:
                    options = [{portrait:true}];
                    break;
            }   
        }
        else {
            // Not on graph page, so flip to portrait regardless of physical device orientation
            options = [{portrait:true}];
        }
        
        cordova.exec(null, null, "Orientation", "setOrientation", options);

Orientation.h

#import <Cordova/CDVPlugin.h>

@interface Orientation : CDVPlugin {
    
}

//Instance Method  
- (void) setOrientation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;

@end

Orientation.m

//
//  SetOrientation.m
//  
#import "Orientation.h" 
#import <Cordova/CDVPluginResult.h>

@implementation Orientation 


// Called from javascript, set the orientation to Portrait when going from graph screen (in Landscape) back
// to other screens - doesn't happen automatically because the physical orientation of the devicehasn't changed
- (void)setOrientation:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options  
{
    //self.viewController.supportedOrientations = arguments;
    NSLog(@"Rotating device in code");

    // Wrap it all in an animation so it looks nicer
    [UIView beginAnimations:@"rotate" context:NULL];
    [UIView setAnimationDelegate:self];
    
    //will rotate status bar
    if ([[options objectForKey:@"portrait"] intValue] == 1) {
        NSLog(@"Portrait");
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    }
    else if ([[options objectForKey:@"portraitdown"] intValue] == 1) {
        NSLog(@"Portrait UpsideDown");
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown];
    }
    else if ([[options objectForKey:@"landscapeleft"] intValue] == 1) {
        NSLog(@"Landscape Left");
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
    }
    else if ([[options objectForKey:@"landscaperight"] intValue] == 1) {
        NSLog(@"Landscape Right");
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
    }
    else {
        NSLog(@"Not defined");
    }
    
    //will re-rotate view according to statusbar
    UIViewController *c = [[UIViewController alloc]init];
    [self.viewController presentModalViewController:c animated:NO];
    [self.viewController dismissModalViewControllerAnimated:NO];
    [c release];
    
    [UIView commitAnimations];
}

@end

So hopefully you find that helpful. It's strange that there is no easy way to achieve this, I would have thought that this was a feature many developers would want for their PhoneGap applications but I found it surprisingly difficult to work this one out.

 

If you found this article useful, please click the +1 button!

 

6 comment(s) for “How to control the page orientations in your iOS PhoneGap application part 2”

  1. Gravatar of Claes Gustavsson


    Claes Gustavsson says:

    Hi David
    Does this work with the latest cordova 2.1.0 and ios6?
    I tested the plugin that you mention but I couldnt get it to work.
    When I tested his plugin, I thought that I could run a function- "landscape();" on the pages that I wanted to rotate, and that the function would have the code for rotating, then you dont have to check if you are on the "graph" page and you can use the same code for many pages. Just a thought!
    Regards Claes
  1. Gravatar of Lutz Huehnken


    Lutz Huehnken says:

    Hi David,

    I agree that this is probably a feature that quite a few developers need, so it's great that you posted a solution.

    Is it supposed to work with Cordova 2.1.0 on iOS 6 as well? I am asking because I can't seem to get it to work - the method is called and I see the log output, but is has no effect regarding the actual orientation.

    Ideas, anyone?
  1. Gravatar of David Conlisk


    David Conlisk says:

    Hi guys,

    I haven't tested it using Cordova v2.1 I'm afraid, but if I do get the chance I'll let you know.

    Cheers,

    David
  1. Gravatar of Shereef


    Shereef says:

    it never worked on iOS 6 for me :/
  1. Gravatar of David Conlisk


    David Conlisk says:

    Hi Shereef,

    Thanks for the info, I've now updated this post to explicitly say that it was built and testing using Cordova 2.0 and iOS 5. Here's hoping someone can help with getting it to work with the latest versions!

    David
  1. Gravatar of Mirko


    Mirko says:

    I didnt test this plugin, but I assume that the bug on the iOS6 webView is the main problem of your work.
    I hope to try this on iOS7 to confirm it.

    Anyway we still need this plugin working on every version > 5 :(

    Regards

Please leave a comment: