Monday, September 26, 2011

Orientations I

This series describes how to improve HelloWorld to support multiple iPhone orientations. In this post, we explore the auto-rotation behavior.


Auto-Rotation
Following the steps in Deploying to your iPhone, HelloWorld now has a home on your iPhone. Saweet! However, there is still room for improvement. For example, many iPhone apps support multiple orientations. That is to say, many iPhone apps function with the phone held sideways (Landscape orientation), and some even upside down.

What about HelloWorld?  Let's see.  Fortunately the iOS Simulator includes the capability to "rotate" the virtual iPhone to test these alternate orientations.  To confirm, first make sure the Xcode scheme is set to "iPhone Simulator". Then, build and run HelloWorld as usual.  You should see something like this:

To rotate the simulation to the right, select Hardware > Rotate Right, or simply press →:
Or, to rotate left, select Hardware > Rotate Left, or simply press :

As one can see, HelloWorld has a couple issues laying out the UI in either Landscape orientation:
  • the "Hello" button seems to have disappeared, 
  • the remaining widgets are not centered. 
Keep going until the virtual iPhone is upside-down:

HelloWorld does not even seem to recognize this orientation!  (Launch the app on your iPhone to confirm these results.)

Let's solve these problems.  First, let's figure out why the upside-down orientation is ignored.  It should not be any different than upright position. Digging deeper, we find in Managing a View Controller's Interface Orientation that the shouldAutorotateToInterfaceOrientation method of UIViewController is responsible for communicating whether or not an app supports a specified orientation.  As the iPhone is rotated, this method is repeatedly invoked to see if each position is supported. Generally speaking, if this method returns YES, the UI is rotated corrspondingly.

What about HelloWorld? Let's check inside HelloWorldViewController to see how it is implemented:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
Looking at the code, it is now obvious why HelloWorld will not rotate to the upside-down position. We have been explicitly prohibiting it! Let's change the implementation to allow all orientations:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Support all orientations.
    return YES;
}
Build and run the app. Then, rotate the device to the upside-down position:

Yay! HelloWorld now responds to the upside-down orientation. Build and deploy the app to your iPhone to confirm.