Size Class Concepts in iOS


With ever more devices and new multitasking features supported by iOS, it’s important to create user interfaces that scale gracefully to different screen sizes. Size classes are the most effective tool for tackling this problem. In this post, we’ll look at what size classes are and how to use them.

Prerequisite Material

Size classes become even more useful when combined with auto layout. If you’re unfamiliar with this system, check out my earlier posts on how to use auto layout in theory and in practice. We’ll be looking at how the two systems work together in this post.

A New Way of Thinking

Before size classes, iOS developers would think carefully about each device and orientation they wanted to support. With size classes, those specific concerns are replaced with a more generalized set of ideas.

Instead of worrying about user interface idiom and orientation, we think only about our interface’s approximate size. Let’s take a look at how to visualize this:

Compact Width,
Regular Height
Regular Width,
Compact Height
iphone_portrait iphone_landscape

With size classes, our interface always fits into one of two categories: regular or compact. This concept applies in both the horizontal and vertical directions.

Breakdown by Device and Orientation

Here’s a handy chart of size classes by device and orientation:

Portrait Landscape
iPhone (5.5 inch) Compact width,
Regular height
Regular width,
Compact height
All Other iPhones Compact width,
Regular height
Compact width,
Compact height
iPad Regular width,
Regular height
Regular width,
Regular height

There are some interesting quirks here. iPad does not have a 1:1 aspect ratio, but its size class is always ‘regular’. Also, iPhones other than the 5.5″ models always have a ‘compact’ width, regardless of orientation.

Implementing Size Classes in Interface Builder

Let’s look at an example of how to manage size classes from Interface Builder:


Editing a layout constraint in the ‘Attributes Inspector’

When examining any object in the Attributes Inspector, we see a section at the bottom that allows us to manipulate its size classes. We can specify multiple size classes in this list. Any time the interface’s size class matches one of the classes in that list, the object will be ‘installed’, i.e. added to our interface.

Using this technique with a NSLayoutConstraint objects allows us to create a totally different layout for each size class. Similarly, using the technique on UIView objects allows us to create totally different view hierarchies.


Faded views or constraints will not be installed in the current size class

When switching between size classes, we can notice some of the icons in the Document Outline look faded. These faded icons signify that the item is in our document, but will not be installed for the current size class.

There are a lot of moving parts here. We can have a different view hierarchy and layout for several size classes. It’s hard to hold all that information in our heads. To relieve some of that cognitive burden, we can preview our interface using the Assistant Editor. Open this editor with the button at the upper right of the Xcode window that looks like a Venn diagram.


How to quickly preview our interface on different size classes

Use the Jump Bar to select ‘Preview’. In this preview tool, we can simultaneously see our interface on multiple devices with different size classes. We can also change the user interface orientation on our preview devices.

Implementing Size Classes in Code

When approaching size classes using only code, we’ll need to use the UITraitCollection class. This class encapsulates all size class information as well as a few other things that will not be covered here.

Many of the classes that we use all the time in iOS development, including UIView and UIViewController implement a protocol called UITraitEnvironment. These trait environment classes allow us easy access to instances of UITraitCollection. We can access it using the traitCollection property.

Let’s look at an example of a UIViewController subclass that gets a callback when the size class changes:

class TraitViewController: UIViewController {
//this function comes from the UITraitEnvironment protocol
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
let horizontalSize = traitCollection.horizontalSizeClass
let verticalSize = traitCollection.verticalSizeClass
let previousHorizontalSize = previousTraitCollection.horizontalSizeClass
let previousVerticalSize = previousTraitCollection.verticalSizeClass
//TODO: make relevant updates to UI for this new size class

When using the traitCollectionDidChange method, we can manage the insertion and removal of NSLayoutConstraint and UIView objects. This allows us to implement the same behavior as the ‘installed’ checkboxes in Interface Builder.


That’s all for now. I hope this post has armed you with enough knowledge of size classes to make your interfaces more robust and flexible across all iOS devices.

3 thoughts on “Size Class Concepts in iOS

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s