Hide this madness

iPad Development 101 – Orientation

Thanks to the introduction of orientation-aware computing devices, designers and developers must now come up with orientation-compatible layouts and implementations. In some cases, switching the orientation will simply modify the layout of the application elements; other times the user experience or application layout could be completely different for each device orientation. Users of orientation-capable devices expect applications to respond to orientation changes, and often rely on them to provide improved/alternative usability options. In this tutorial we will explore the iPad’s orientation capabilities and look into a few methods for orientation implementation.

First lets go over the basics for enabling and working with orientation specific content on the iPad.

If you have not already, you should read the iPad Human Interface Guidelines which includes a sub-section on iPad User Experience Guidelines. These documents provide a good overview of what Apple expects developers to include in their applications in order to provide an optimal and consistent user experience across all applications.

The Code

To get started with orientation on the iPad, lets first take a look at the function provided to us by Xcode in the template .m file.

// Override to allow orientations other than the default portrait orientation.
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

By default the application will auto-rotate to the orientation of the device.
To disable the auto-rotation, set the return statement to “NO” and launch the application.

You should notice your application window is fixed now and does not respond to the device orientation.

When building iPad apps, developers are encouraged to take advantage of the device orientation and not only provide support for all orientations, but to include additional functionality or layout options when it makes sense to do so.

Beyond the Fundementals

The code above will implement the standard orientation capabilities of the iOS framework. There will be many cases where you would like to switch a view entirely when the device is rotated from one orientation to another.

Lets take a look at one way we could achieve such functionality.

For this example we will create a test project called OrientationBasics.

In you application header ( OrientationBasicsViewController.h ), we add the following lines to create our two main orientation base views, additionally we add the UIDeviceOrientation to keep track of what the current position the device is.

@interface OrientationBasicsViewController : UIViewController {
	IBOutlet UIView *mainPortraitView;
	IBOutlet UIView *mainLandscapeView;
	UIDeviceOrientation orientation;
}

@property (nonatomic, retain) UIView *mainPortraitView;
@property (nonatomic, retain) UIView *mainLandscapeView;

// Simple function to be user for clearing views
(void)clearCurrentView;

Notice the clearCurrentView function, this will come in handy when we need to clear the active view and display our orientation specific view.

Now lets move to our implementation file ( OrientationBasicsViewController.m ) and add the rest of our logic.

First we synthesize our two main orientation views.

@synthesize mainPortraitView;
@synthesize mainLandscapeView;

We should also release these objects from memory, lets edit the dealloc function to read as follows:

(void)dealloc
{
	// Release orientation views
	[mainPortraitView release];
	[mainLandscapeView release];
    [super dealloc];
}

Next we add some logic to the viewDidLoad function for keeping track of the device orientation.

// Make the view aware of orientation changes.
	[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:@"UIDeviceOrientationDidChangeNotification"  object:nil];
	orientation = [[UIDevice currentDevice] orientation];
	if (orientation == UIDeviceOrientationUnknown || orientation == UIDeviceOrientationFaceUp || orientation == UIDeviceOrientationFaceDown) {
		orientation = UIDeviceOrientationPortrait;
	}

Now we can add our function to handle what happens when the device orientation is changed.

Below your viewDidLoad function add this function for didRotate.

// orientation view swapping logic
(void)didRotate:(NSNotification *)notification {
	UIDeviceOrientation newOrientation = [[UIDevice currentDevice] orientation];
	if (newOrientation != UIDeviceOrientationUnknown && newOrientation != UIDeviceOrientationFaceUp && newOrientation != UIDeviceOrientationFaceDown) {
		orientation = newOrientation;
	}

// Do your orientation logic here
	if ((orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight)) {
		// Clear the current view and insert the orientation specific view.
		[self clearCurrentView];
		[self.view insertSubview:mainLandscapeView atIndex:0];
	} else if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {	
		// Clear the current view and insert the orientation specific view.
		[self clearCurrentView];	
		[self.view insertSubview:mainPortraitView atIndex:0];
	}
}

Also be sure to include the function for clearing the current view.

// Remove current view when loading a new view
(void) clearCurrentView {
	if (mainLandscapeView.superview) {		
		[mainLandscapeView removeFromSuperview];
	} else if (mainPortraitView.superview) {
		[mainPortraitView removeFromSuperview];
	}
}

Last but not least, we will switch over to Interface builder to add our views and make connections.

Double click on the OrientationBasicsViewController.xib file to launch the interface builder.

Drag out two new UIViews into the project Document window and rename the views to mainLandscapeView and mainPortraitView.

Next Control -> Drag from the File’s Owner icon to each of the views and choose the appropriate outlet. Your connections should look as follows when you click on the File’s Owner icon.

Now double click on each of the views to open them, then drag a UILabel and set the text value to something unique for each view.

This video provides a visual overview of the connections we just made in Interface Builder.

You can now save the .xib in Interface Builder and return to Xcode to test the project.

To test the project choose the build and run option from the build menu or click the build icon.

If you have followed along and haven’t come across any typos or errors, you should now have see your application launch and load the first view, portrait or landscape, based on the current orientation of the device.

Try launching the application with the device in different orientation, also notice when you change the device orientation when the app is running, you views will be updated to reflect the current orientation.

Download the sample application: OrientationBasics

  1. [...] Thanks to the introduction of orientation-aware computing devices, designers and developers must now come up with orientation-compatible layouts and implementations.Continue Reading… [...]

  2. Good post and this post helped me alot in my college assignement. Thank you on your information.

    Sep 22nd, 2010
  3. some minor problem to be corrected – change && into the proper entities in a code :)

    I’ve spent several hours to implement this stuff, before I finally got here, thanx Geoff!

    eof
    Nov 28th, 2010
  4. lol, just check the code for entities, that where parsed by WordPress, as well as parsed from my comment :)

    eof
    Nov 28th, 2010
  5. @eof thanks for pointing that out, I’ve updated the example code.

    Geoff Palin
    Geoff Palin
    Dec 10th, 2010
  6. [...] This guide largely based on the excellent guide provided by Geoff Palin at A Series of Tubes. [...]

  7. Well done, thank you very much indeed, Geoff. I tried this with two different png-images (1024 x 748 and 768 x 1004 to mind the statusbar). It works fine the first and the second time, but after changing orientation the third time something goes wrong. It seems that I can see a part of the last picture, the new one only appears partly. I checked the code twice, no typo.

    May 21st, 2011
  8. hi again,

    First, small disclaimer ;)

    I am total noob and not even a coder, just tryin to figure out some basics and write some iOS mockups, so forgive me asking dumb questions ;)

    Any idea how to use this code with swipe gestures (UISwipeGestureRecognizer probably)?

    eof
    May 23rd, 2011
  9. So… what about if you want to have connections in your views for IBOutlets and IBActions?

    How would one use interface builder to set up the relationships for the portrait & landscape views? Is there special things to set up or watch out for?

    Jun 1st, 2011
  10. Started migrating from Java yesterday with the first few of Paul Hegarty’s Stanford iTunesU lectures for some basics.

    Your very clearly presented orientation tutorial has helped me immensely in porting parts of an Netbeans RCP app to iOS. Thanks.

    --NIck/
    Aug 15th, 2011
  11. Hi,

    Good post and this post helped me a lot too. It provided me complete information on the orientation with an easy way.

    But today, I found one more thing,this trick doesn’t work on latest version of iOS i.e iOS6. The view does’;t get rotate accordingly as in previous version even after implementing the iOS orientation methods :

    - (BOOL) shouldAutorotate;
    - (NSUInteger)supportedInterfaceOrientations;

    I am not sure how it will work now.

    Ajay
    Dec 5th, 2012

Add a comment

Comment feed
The better to greet you with
No one will ever see this
Your pride and joy
The reason this comment form exists

The crew behind ASOT

We're a team of interactive, software, and business intelligence experts skilled in the design, construction, and management of online enterprise systems.

Visit The Jonah Group site

Get in touch with us