A few years ago, were was only two devices: an iPad and an iPhone. Storyboards were separate for iPads and iPhones. For any device, there was extra code necessary to use the same app in landscape and portrait. With new phone sizes, like the iPhone 6 plus, the iPad Pro or the retro-sized iPhone SE this became a bit more of a problem. Developers could design a different storyboard for every size and orientation. That would be an excessive amount of work. Every new version of the phone or tablet would need to be different, with a separate storyboard. For all devices running iOS 10, that is four iPhones in portrait and landscape, three iPads in Portrait and landscape and ten panels for iPad multitasking. To develop a storyboard or code for each device would mean designing for twenty-four views . If you hear about device fragmentation this is what people are talking about: different devices need different layouts because their screens are different sizes. It’s not just mobile devices that have this problem. AppleTV might run your iOS app. Televisions vary widely in size. AppleTV needs to change the view to handle those differences.
Over that last few years, there have been many solutions to adaptive user interfaces, which are interfaces that adapt their size and shape automatically to the device or window they happen to be in. Apple’s solution to this problem is auto layout, which lets the system do the hard work. Using relations between views, we describe how to layout the user interface.
In iOS 8, Apple introduced size classes, a way to describe any device in any orientation. Size classes rely heavily on auto layout. Until iOS 8, you could escape auto layout. IN iOS8, Apple changed several UIKit classes to depend on size classes. Modal views, popovers, split views, and image assets directly use size classes to determine how to display an image. Identical code to present a popover on an iPad causes a iPhone to present a modal view.
Different Size Classes
There are two sizes for size classes: compact, and regular. Sometime you’ll hear about any. Any is the generic size that works with anything. The default Xcode layout, is width:any height:any. This layout is for all cases. The Horizontal and vertical dimensions are called traits, and can be accessed in code from an instance of
UITraitCollection. The compact size describes most iPhone sizes in landscape and portrait. The trait of most importance is the width trait. The width is compact on all phones but the iPhone Plus models. There is one exception: the width in landscape is regular for an iPhone 6 Plus, which can cause some confusion. iPhone 6 Plus acts like a iPhone in portrait but an iPad in landscape. For both width and height, the full iPad and the 2/3 iPad for multitasking is the regular size. The 1/3 and 1/2 iPad multitasking modes are compact in width and regular in height.
There’s one more variation to compact and regular. You can specify both compact and regular with Any. When you add Any to Compact and Regular there are nine size classes the developer can use.
Prior to Xcode 8, developers would have to know what all these sizes are and which device each belonged. That changed in Xcode 8 with a new user interface for Interface Builder. Xcode displays as selection of devices, the developer selects the devices, then Xcode previews the layout on that device.
The any class makes working with size classes a bit more generic, saving work. Our designs start in the width:any height:any size class, covering all cases. If we need a special design, then we use that specific size class. Prior to Xcode 8, any needed to be explicit, and in some places you’ll find explicit uses of any still. Often Xcode 8 hides Any from you, making it implicit instead of explicit.
Open a new single view project in XCode. Go to the storyboard. At the bottom left storyboard you’ll find this:
the iPhone 6s is the default device for Interface Builder. Click this text. A new toolbar appears below, with the iPhone6s in portrait selected.
Select the iPad Pro 12.9″ on the left. The toolbar changes to include all size classes for an iPad Pro.
You’ll notice the screen looks blank. The iPad is too big for the screen. In the center of the toolbar click the 100%. In the menu that appears, click the 50%.
To make the device easier to see, I changed the background color attribute of the view to light gray.
Select the iPhone 4s and under Orientation set the orientation to Landscape. We get a preview of a iPhone4s in landscape. Zoom in to 100% to see it better.
All of this is in the Any size. To change the size for devices, you can click the Vary for Traits button.
So far you’ve previewed a blank storyboard. Click the icon for a portrait phone. Add two buttons labeled Button 1 on the top of the scene and Button 2 towards the bottom. In the attributes inspector, Set the Text Color to White and the background of the button to Black.
You’ll need a little auto layout to take advantage of size classes. If you’ve never used auto layout, we’ll keep it simple. Select Button 1. Find the pin button in the Auto Layout menu on the lower right side of Interface builder. Click to get a popup.
In the highlighted box pin to the view above by typing 10 and hitting tab on your keyboard. The I-Beam below turns black, and the cursor moved to the left pin. Type 10 and tab again to pin the button to the right margin 10 points. Type 10 and tab one more time to pin the right side to the right margin by 10 points. Be sure to type tab to make sure the I-beam shows. Toward the bottom of the popup, You’ll find the Update Frames button. Change the value from None to Items of new constraints. Your popup should look like this:
Click Add 3 constraints and the constraints will appear on the storyboard, stretching the button to the correct size and position.
Select Button 2 on the bottom. You’ll pin this to the bottom. Click to get a popup. Tab past the first box without entering anything. try 10 then tab for the left pin, 10 and tab for the right pin, and 10 and tab for the bottom pin. Again set Update frames to Items of new Constraints. The popup should look like this.
Add the three constraints. Your storyboard should look like this:
Click the iPad Pro 9.7″ icon. Close the navigation and attributes inspector panels to give yourself room. Change the scale to 75%. You’ll see this:
The horizontal and vertical dimensions we refer to as traits. You can change one or both traits of the displayed device. The current traits are found after the name of the device in the view as button. The current view show us a width of regular(wR) and height of regular(hR). The default iPhone6s in portrait is (wC hR) for compact width, Regular height.
Select an iPhone 6s Plus(wR hC) in landscape in the toolbar. All phones in landscape are compact width and compact height except iPhone Plus. The iPhone plus models are regular width not compact. On regular width devices, usually users will hold with both hands on the sides, using their thumbs across the device for most button presses. On compact width devices, users typically will hold from the bottom for compact width devices, using the thumb up and down. You’ll now change all devices with a regular width to place the buttons on the sides, which is the easier to use place for thumbs to contact them.
Click the Vary for Traits button on the right side of the size class toolbar. A popup appears.
Check the Width checkbox. The toolbar changes color and displays all size classes affected.
Click in the newly colored area to close the popup. You are now in the mode that changes only the devices with a regular class width. Open the attributes inspector, and change to the ruler for the size inspector.
Select the Button 2. Scroll down the size inspector until you find this constraint.
The storyboard looks like this:
Add the constraint. Select the Button 2. Type 10 , then hit tab for the top constraint. Select Items of new constraints like this:
Add the new constraint. The layout now looks like this:
Go to an iPad Pro 9.7″ in portrait. At 75% scale it looks like this:
Under Adaptations in the size class toolbar, click the middle button. This is a multitasking view, which is compact width. The buttons are on the top and bottom again.
You can also change attributes based on the size classes. Click the gray view. Go to the attributes inspector and click the + next to the background attribute.
A popup appears:
The current device’s traits appear in the box. Change Width to Regular and Height to Any to make this an attribute of all regular width devices.
Click Add Variation. A new background attribute for regular width appears under the default one.
Change the wR background color to another color. I used Orange(#FF8000). Nothing changes on the storyboard. You are still on a compact width. Click the icon in Adaptation to go back to regular size. The background is Orange.
You can browse though the other devices to see which ones have orange backgrounds and which have gray ones. As you can see, Size Classes in Xcode 8 are quite powerful ways of laying out your project easily, while customizing the layout for different devices.
This is sample of what awaits you in Practical Auto Layout for Xcode 8. Using simple, practical, easy to follow examples, you will learn how to master auto layout, size classes and stack views on the Xcode 8 storyboard. You will learn how to make universal apps quickly easily and in far less time than ever before.