The ability to create interfaces that display correctly regardless of your iDevice’s screen size or orientation is one of the key features that users expect in an application. This lesson explores the Xcode Auto Layout system and three different ways of adding rotatable and resizable interfaces to your apps.

You can use almost every iOS interface widget available, create multiple views and view controllers, add sounds and alerts, write files, and even manage application preferences, but until now, your applications have been missing a very important feature: responsive interfaces. The ability to create interfaces that display correctly regardless of your iDevice’s screen size or orientation is one of the key features that users expect in an application—and the key goal of responsive interface design.

This hour’s lesson explores the Xcode Auto Layout system and three different ways of adding rotatable and resizable interfaces to your apps. As you read this hour’s lesson, an important fact to keep in mind is that there are many different ways to solve the problem of responsive interface design. What works best for you may be entirely different than what I describe here.

Responsive Interfaces

Years ago, when I had my first Windows Mobile smartphone, I longed for an easy way to look at web content in landscape mode. There was a method for triggering a landscape view, but it was glitchy and cumbersome to use. The iPhone introduced the first consumer phone with on-the-fly interface rotation that feels natural and doesn’t get in the way of what you’re trying to do.

The iPhone 5 shakes things up by introducing the first 4” iPhone screen with a different aspect ration and resolution than the traditional 3.5” models. Does this mean that you need to worry about iPhone 3.5” displays, 4” displays, iPad displays, and portrait and landscape orientations for each? Nope! The iOS Auto Layout system makes it easy to adapt to different resolution displays and change your interface layout as your device resolution changes.

TIP

Using Auto Layout to adapt between 3.5” and 4” screens is no different from adapting to a device that rotates between portrait and landscape. The resolution changes on-the-fly in the case of rotation, but you’ll use the same tools to compensate. The only difference is that you can control whether or not your application handles different orientations—you can’t control whether or not your users buy a 4” iPhone screen.

Although you should definitely plan to accommodate all sizes of the iPhone screen in your iPhone apps, the decision to handle rotation is entirely up to you. Consider how the user will be interfacing with the app. Does it make sense to force a portrait-only view? Should the view rotate to accommodate any of the possible orientations the phone may assume? The more flexibility you give users to adapt to their own preferred working style, the happier they’ll be. Best of all, enabling rotation is a simple process.

TIP

Apple’s user interface guidelines for the iPad strongly encourage the support of any orientation/ rotation: portrait, left landscape, right landscape, and upside-down.

Enabling Interface Rotation

The projects that you’ve built to-date have had supported limited interface rotation because of a single line of code in a single method in your view controller. This is added by default when you use one of Apple’s iOS templates.

When an iOS device wants to check to see whether it should rotate your interface, it sends the supportedInterfaceOrientations message to your view controller. The implementation of supportedInterfaceOrientations just returns a value that describes the supported orientation. To cover more than one orientation, you just return the list of constants you want to use, separated by the | character.

There are seven screen orientation support constants, as listed here.

Orientation

Orientation Support Constant

Portrait

UIInterfaceOrientationMaskPortrait

Portrait upside-down

UIInterfaceOrientationMaskPortraitUpsideDown

Landscape left

UIInterfaceOrientationMaskLandscapeLeft

Landscape right

UIInterfaceOrientationMaskLandscapeRight

Any Landscape

UIInterfaceOrientationMaskLandscape

Anything but upside-down

UIInterfaceOrientationMaskAllButUpsideDown

Anything

UIInterfaceOrientationMaskAll

For example, to allow your interface to rotate to either the portrait or landscape left orientations, you implement supportedInterfaceOrientations in your view controller with the code in Listing 16.1.

Listing 16.1. This Method Activates Interface Rotation

The return statement handles everything. It returns the combination of the two constants that describe landscape left and portrait orientations.

NOTE

In addition to adding this method to your view controllers, you must also choose the orientations supported by your app by clicking the Supported Interface Orientation icons in the application summary. This is described in the section “Setting Supported Device Orientations” in Hour 2, “Introduction to Xcode and the iOS Simulator.”

At this point, take a few minutes and go back to some of the earlier hours and modify this method in your view controller code to allow for different orientations. Test the applications in the iOS simulator or on your device. For iPhone apps, try switching between 3.5” and 4” displays.

Some of the applications will probably look just fine, but you’ll notice that others, well, don’t quite “work” in the different screen orientations and sizes, as shown in Figure 16.1 (ImageHop, from Hour 8, “Handling Images, Animation, Sliders, and Steppers”).

Everything we’ve been building has defaulted to a portrait design and, for the iPhone, a 4” screen, so how can we create interfaces that look good regardless of the orientation and size of the screen? We obviously need to make some tweaks.

Designing Rotatable and Resizable Interfaces

In the remainder of this hour, we explore several different techniques for building interfaces that rotate and resize themselves appropriately depending on the device, or when the user changes the device’s screen orientation. Before we get started, let’s quickly review the different approaches and when you’d want to use them.

Auto Layout

The Xcode Interface Builder (IB) editor provides tools for describing how your interface should react when it is rotated or when the size of the screen can be variable. It is possible to define a single view in IB that positions and sizes itself appropriately—no matter what the situation—without writing a single line of code. This bit of Apple magic is called Auto Layout. It will be your best friend and worst enemy in creating responsive interfaces.

Using Auto Layout should be the starting point for all interfaces. If you can successfully define portrait and landscape modes in a single view in the IB editor, your work is done.

Unfortunately, Auto Layout doesn’t work well when there are many irregularly positioned interface elements. A single row of buttons? No problem. Half a dozen fields, switches, and images all mixed together? Probably not going to work.

Programming Interfaces

As you’ve learned, each UI element is defined by a rectangular area on the screen: its frame property. If we programmatically define an application interface, we can make it into anything we want. Although this might sound challenging, it’s actually very simple and very effective for creating interfaces that vary dramatically between different sizes and orientations.

For example, to detect when the interface rotates, we can implement the method didRotate-FromInterfaceOrientation in our view controller. The view controller property interface Orientation will tell us the current orientation of the interface, by containing one of these four constants:

Orientation

Current Orientation Constant

Portrait

UIInterfaceOrientationPortrait

Portrait upside-down

UIInterfaceOrientationPortraitUpsideDown

Landscape left

UIInterfaceOrientationLandscapeLeft

Landscape right

UIInterfaceOrientationLandscapeRight

The drawback to doing everything in code is that you are doing everything in code. It becomes very difficult to prototype interface changes and visualize what your final interface will look like. In addition, it is harder to adapt to changes in the future. It’s best, in my opinion, to use a combination of Auto Layout with hand-coded interfaces to provide the best flexibility and speed of development.

Swapping Views

A more dramatic approach to changing your view to accommodate different screen orientations is to use entirely different views for landscape and portrait layouts. When the user rotates the device, the current view is replaced by another view that is laid out properly for the orientation.

This means that you can define two views in a single scene that look exactly the way you want, but it also means that you must keep track of separate IBOutlets for each view. Although it is certainly possible for elements in the views to invoke the same IBActions, they cannot share the same outlets, so you’ll potentially need to keep track of twice as many UI widgets within a single view controller.

NOTE

To know when to change frames or swap views, you will be implementing the method didRotateFromInterfaceOrientation in your view controller. This message is sent to a view controller when the interface has finished changing orientation. If you want to react prior to the orientation change taking place, you could implement the willRotateToInterfaceOrientation:duration method.

TIP

Apple has implemented a screen-locking function so that users can lock the screen orientation without it changing if the device rotates. (This can be useful for reading while lying on your side.) When the lock is enabled, your application will not receive notifications about a change in orientation. In other words, to support the orientation lock, you don’t need to do a thing.