Creating a Landscape App in AIR for iOS

Often when making games, or even applications, you’ll want to create an app that only respects Landscape orientation, and not portrait.

AIR for iOS has a fairly big issue when it comes to making a landscape only app: When setting an app to Landscape, it will only display in the default landscape position, flip the device over and the app will not rotate.  If Apple picks up on this, they will actually reject your app from the App Store!

Currently, the recommended method for a landscape app in AIR, is to set <autoOrients>false</autoOrients> and <aspectRatio>landscape</aspectRatio>, this locks your screen to landscape when it’s initially launched, and prevents the screen from rotating at all. This is the best you can get as far as initial setup goes, problem is, since it does not rotate at all, it will never flip to the “other” landscape view…

Now, the solution is one of those ones that “should” be easy, but ends up being a complete pain in the ass. All you “should” need to do is:

* Listen to the stage, for StageOrientationChange event.
* Use event.afterOrientation to determine if we’re flipping to Portrait
* Use event.preventDefault() to stop the rotation if it is.

This becomes complicated though, because AIR doesn’t actually tell you whether afterOrientation will be portrait or landscape. Instead you get DEFAULT, ROTATED_LEFT, ROTATED_RIGHT, and UPSIDE_DOWN, but different devices treat the StageOrientation values differently. In some cases StageOrientation.DEFAULT is portrait (iPhone, iPad, most Android Phones), and in others it’s landscape (Android Tablets / Phones).

So, first  we need to figure out what those value mappings really correspond to, then we can decide whether or not to block the event. Here’s the code for that, which is completely cross platform, will work on Android, iOS and anything else:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//You want to catch the change before it happens, so listen for ORIENTATION_CHANGING not ORIENTATION_CHANGE.
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging, false, 0, true);
 
protected function onOrientationChanging(event:StageOrientationEvent):void {
	//Determine whether DEFAULT and UPSIDE_DOWN == landscape, this varies from device to device.
	var isDefaultLandscape:Boolean = true;
	var isLandscapeNow:Boolean = (stage.stageWidth > stage.stageHeight);
	if(isLandscapeNow && (stage.orientation == StageOrientation.ROTATED_LEFT || stage.orientation == StageOrientation.ROTATED_RIGHT)){
		isDefaultLandscape = false;
	}
	//Are we switching to a landscape mode? If we are, use preventDefault to stop it.
	var goingToDefault:Boolean = (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN);
	if((goingToDefault && !isDefaultLandscape) || (!goingToDefault && isDefaultLandscape)){
		event.preventDefault();
	}
}

This is tested and working on Nexus One, iPad, iPhone, Playbook and Moto Xoom.
 
 

Written by

7 Comments to “Creating a Landscape App in AIR for iOS”

  1. Jonathon says:

    Awesome post! Thanks for this!

  2. Adam Zucchi says:

    Thanks for the post. I was puzzled as to why in the publish settings for AIR iOS an option was not available for only landscape or only portrait if the developer still wanted the device to auto orient. Much appreciated!

  3. Adam Zucchi says:

    Hey Shawn,

    One quick question. I am running into a problem where I am using what you have provided above, and instantiating a native extension context that opens the in app mail composer, the issue is that the in app mail composer actually comes in upside down, and it also has flipped my application sitting behind it upside down. On the ‘cancel’ of the mail composer, my app resumes in the correct orientation. This seems extremely odd, and I am wondering if it is somehow related to the preventDefault() from above?

    I am setting my aspectRatio to landscape and autoOrients to true with your code applied as well. I only want my application to run in landscape mode, but to auto orient to the other landscape view if the user turns the device.

    Thoughts on why the mail composer comes in upside down?

    Any help would be greatly appreciated. Please feel free to contact me via email with any thoughts/comments as well.

    Thanks.

    Adam

  4. ekeeper says:

    Thank you for this article!!! :)

  5. whgandalf says:

    excellent, this is working perfectly! thanks for your help, :)

  6. A little update for Flex applications, on applicationCreate event :
    “stage” online don’t fire anything.

    FlexGlobals.topLevelApplication.stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging, false, 0, true);

    Thanks for the initial Tips ! :)

    Enjoy !

Leave a Reply to Jonathon

Message