An introduction to Size Classes for Xcode 8

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.

size classes 9_1_1

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.

Viewing Size Classes

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:

2016-09-02_06-29-00

the iPhone 6s is the default device for Interface Builder. Click this text. A new toolbar appears below, with the iPhone6s in portrait selected.

2016-09-02_06-31-53

 

Select the iPad Pro 12.9″ on the left. The toolbar changes to include all size classes for an iPad Pro.

2016-09-02_06-36-40

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%.

2016-09-02_06-40-09

To make the device easier to see, I changed the background color attribute of the view to light gray.

2016-09-02_06-43-44

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.

2016-09-02_06-47-16

All of this is in the Any size.  To change the size for devices, you can  click the Vary for Traits button.

A Little Auto Layout

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.

2016-09-02_06-56-34

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 pinMenuButtonin the Auto Layout menu on the lower right side of Interface builder. Click pinMenuButtonto get a popup.

2016-09-02_07-01-19

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:

2016-09-02_07-07-01

Click Add 3 constraints and the constraints will appear on the storyboard, stretching the button to the correct size and position.

2016-09-02_07-11-20

Select Button 2 on the bottom. You’ll pin this to the bottom. Click pinMenuButtonto 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.

2016-09-02_07-16-10

Add the three constraints. Your storyboard should look like this:

2016-09-02_07-17-38

Click the portrait orientation icon portrait icon 4sand the view resizes the buttons:

2016-09-02_07-20-16

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:

2016-09-02_07-25-30

Varying a Trait

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.

2016-09-02_07-30-41a

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.

2016-09-02_07-43-42

Check the Width checkbox. The  toolbar changes color and displays all size classes affected.

2016-09-02_07-46-05

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.

2016-09-02_07-48-38

Select the Button 2.  Scroll down the size inspector until you find this constraint.

2016-09-02_07-50-34 Select it and press delete on your keyboard. Select Button 1. Find this constraint  and delete it:

2016-09-02_07-53-15

The storyboard looks like this:

2016-09-02_07-54-54

Select Button 1.  Click on the pin constraint button pinMenuButton. Select the bottom constraint and type 10 , then hit tab. Select Items of new constraints. The popup should look like this:

2016-09-02_07-58-38

Add the constraint. Select the Button 2. Type 10 , then hit tab for the top constraint. Select Items of new constraints like this:

2016-09-02_07-59-37

 

Add the new constraint. The layout now looks like this:

2016-09-02_08-01-45

 

Press Done varying.  The highlight color disappears. Change to Portrait 2016-09-02_09-47-12and the buttons are on the top and bottom.

2016-09-02_08-48-58

Go to an iPad Pro 9.7″ in portrait.  At 75% scale it looks like this:

2016-09-02_09-48-53

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.

2016-09-02_08-53-24

Class Size Variations on Attributes

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.

 

2016-09-02_08-55-17

A popup appears:

2016-09-02_09-05-07

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.

2016-09-02_09-07-03

Click Add Variation. A new background attribute for regular width appears under the default one.

2016-09-02_09-08-03

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 2016-09-02_09-12-10 icon in Adaptation to go back to regular size. The background is Orange.

2016-09-02_09-13-32

 

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.

Pratical Autolayout
for Xcode 8

practical-autolayout-x8-newsletter

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.

Download_on_iBooks_Badge_US-UK_110x40_090513

43 Replies to “An introduction to Size Classes for Xcode 8”

  1. Actually, following this guide i was able to do what i wanted on an ipad interface. The only thing which is not clear is: how do i actually change the constant of a constraint, for a specific size class only? The tutorial, just shows how to delete and create a new constraint, but why do this if i have to (if…) modify the constant just for that size class?
    Great tutorial anyway, thanks!

    1. Once you specified a size class to vary, just modify the constant for the constraint. Xcode keeps track of those changes. To make the Button 2 smaller for example, Click the iPad, vary for traits and select width. In the size inspector click Edit for the Top Space to Top Layout Guide constraint.Change from 10 to 100. Press Done Varying.

      You’ll note in the size inspector a button that has this class size and all class size just above the constraints. This let you see which constraints you’ve made to specific class sizes. the one dimmed out do not apply to the currently selects class size.

      I’ll warn you be careful with this. Most of my conflicting constraints start with modifying constraints like this.

    1. If things are a mess, I’d try cleaning out the constraints and starting over. removing the constraints keep everything in the same size.

      Generally here’s the rule for dealing with constraint conflicts: the error panel will tell you all the conflicts. you need to delete constraints until you are left with one per conflict. It’s your task to figure out which one.

      You can also check for dimmed out constraints that are causing the conflict.Those are ones found in specific size classes. A big culprit is always iPhone 6Plus for constraints that are messing everything else up.

    1. IF you made a change to regular height constraints on an iPad, it will affect the phones in portrait. If you want to make changes to an iPad, change the width only. General rule which even Apple follows in presenting modals is to specify the device by the width only. the only exceptions are iPhones in landscape which have a compact height. The big pain in the posterior regions is the iPhone plus which has the regular width, compact height.

      1. eh, sorta… you could also vary by BOTH width and height to vary all iPads only. varying by width only will also vary the plus size phones

      2. Not a few years ago before auto layout, which was what I was referencing. As for after auto layout yes, a regular height, regular width device is an iPad, but I tend to stay with the width only because of the plus and multitasking panes. There’s less chance of conflicting constraints if you make a layout for all regular width devices first and specify the iPhone plus as a regular width, compact height last.

  2. The only thing which is not clear here, is how to edit constraints for iPad in landscape. iPad size class is same in portrait and landscape. (both are W-Regular H-Regular). what can I do?

    1. That is the $1,000,000 question. Apple for some reason has the size classes as though the iPad is square, which is why the Xcode 7 storyboard is square. A lot of landscape cases involving split-views or multitasking are taken care of for you. I have no good idea that I’ve actually tried. That said there are a few hacks. If you really need to do something different in landscape, you could change the size class in your application to Height:compact and design for an iPhone 6 plus. That would be in the traitsCollection property. That’s an article and a half to describe, but there’s the current class reference. There is a wwdc2015 video on trait collections, but I can’t seem to find it. It may be buried in one of the auto layout ones.

  3. Hi Steve, yesterday as a beginner I bought your e-book for the ‘Practical Autolayout for Xcode 7’ from Amazon not realising the changes to Xcode 8 which I have installed. I must admit I am now stumped, only getting to Chapter 3 of your book and it says Size Classes default to wAny hAny which they no longer do in Xcode 8 and I cannot find out how to reset this default.

    1. I’m late on the book release and its one reason I posted this lesson. I’m hoping for late October release on the Xcode 8 version.

      As long as you don’t hit the Vary for Traits button, you are in width:Any Height:any. So for chapter 3, don’t do anything, you are already in that default. This post will replace chapter 5. In chapter 6, when I discuss Any Width, Compact height, click the iPhone6s, and landscape. Select Vary for Traits, and check on the Height only. When this or any chapter I vary constraints is complete, click Done Varying. When I discuss in Chapter 8 Width:Regular,Height:any Click the iPad (Landscape or portrait doesn’t matter), click the Vary for Traits button for the width trait only. In Chapter 9, When I discuss the Width:Regular,Height:Compact Click the iPhone 6s Plus in landscape and select both height and width. Anywhere else in the book where those size constraints come up, use those sizes.

      For any given size class, see the chart at the top of the post and vary for traits for that device. Or, I’ll just repost it here:
      Size classes

      Like I said I’m looking for an October release. I’m very aware the sooner the better.

    2. You are welcome. It was a great question. Than you very much for asking it. This weekend I need to get an errata page up for those with the same problem. My apologies for not getting the new version out sooner.

  4. Steven, Thanks very much for this great tutorial. I’m new to iOS development and have been studying Xcode and just moved to Xcode 8 and noticed that auto layout has changed and found your tutorial. At first I wasn’t ‘getting’ what you meant by you are ‘always in any/any mode’, but after going through the tutorial it made sense. I think this new system is much better than the earlier one. Your tutorial is great; it just has enough info to illustrate the major points; obviously to get fluent with it one must use it and practice. Thanks again!

      1. Thanks for the info; I will be eagerly awaiting the book. Roughly, when will it be available to purchase? Not sure how long it typically takes from the time a book is completed to when it is available to buy.

      2. Steven, I have been playing around with this stuff since going through the tutorial and had a comment on this workflow with regards to how the UI has been designed by Apple. I would be interested in getting your feedback. After getting familiar with this I see that for tweaking the constraints (which we did first) you have to use the ‘Vary for Traits’ button. We did this for deleting some of the existing constraints and then adding the one we needed. Then after all this was done we got out of ‘Vary for Traits’ mode. However, for the tweaking of the background color (an attribute), we didn’t use the ‘Vary for Traits’ button. You just use the ‘+’ icon to access that functionality {‘Introduce Variation Based On). Is this basically the over-arching design? For Attributes you use the ‘+’ icon and don’t use ‘Vary for Traits’ While for changing the size and position of UI elements (along with contraints) you have to go into ‘Vary for Traits’ mode via that button. Does this basically sum it all up and is this a good way to compartmentalize all of this? Thanks for any info. -jonR

      3. Yes. Constraints you change in vary for traits. Attributes (and selected attributes at that) can be varied by class size only by the plus sign. You can hit the plus while varying for traits too, where it will default the traits in the popover to the current variation.

      4. Steven, Thanks for the feedback. Good luck with fighting the resistance at the end of the project and enjoy the remainder of the World Series!
        cheers,
        jonR

  5. i have developed an app in xcode 7 and while am updating to xcode 8 the xib files gets view colllapse and designs i made like tableview, button etc. are completely diminished at corner of xib. How can i get back my view

    1. Generally that comes from updating without enough constraints. Select each view n the document outline and add moe constraints first. Any view needs at least enough constraints to specify a position and a horizontal and vertical size.

      1. You can’t. That’s a auto rotation setting, not an auto layout setting. Autorotation is in the view controller, not the view. In code, you’ll have to check the traits in the view controller and prohibit wC hC from rotating. I’m not sure what the code for that is, but that’s what needs to be done.

  6. Hey Steven Lipton That’s a great tutorial, but i want to create 3 buttons “side by side” for 3 rows (Total 9 buttons) and i want to see all are placed well for all iphone’s(4s,5,5s,6,6s,6splus,7 and for ipads ) while i am taking one device simulator and creating it is working for that device only when tested in other simulator it gets overlapped or buttons gets conjusted (improper fittings) so how to make and see for all iphone devices any tutorial or documentation will be greatly appreciated Thank you.

    1. The easy answer is stackviews. Make three rows of three buttons each. Select a row of buttons and hit the stack view button Stack view Button. Set the attributes of the stack view to horizontal axis, Fill alignment and fill equally distribution. Do the same for the other rows so you have three rows. Select the three rows, which is best done in the document outline. Hit the stack view button again. Set the attributes to Vertical axis, Fill alignment Fill equally distribution. Pin the stack view to the super view using auto layout. Be sure to pin all four sides or give a size since stack views have no intrinsic size.

      Speaking if intrinsic size. I’m thinking you forgot to set the width or height on one or more of your buttons. Check all of them to see what is going on. You probably have a ambiguous constraint error somewhere as well which might help you find the problem.

      1. Steven, thank you, that outline was most excellent and helped me reassess a layout i was troubled with!

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s