Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB...

8
Xcode 9 IB Layout Tutorial Page of 1 8 By Christopher Durham Xcode 9 Interface Builder Layout By Christopher Durham Why? macOS and iOS devices come in many dierent screen sizes and aspect ratios. By utilizing the tools that Interface Builder gives you, it’s possible to write interfaces that gracefully adapt to many dierent screen sizes. Resources All sources and assets used in this tutorial can be found at http://cs.furman.edu/ ~cdurham/tutorials/Xcode9-IB-layout/. The raw image assets are at http:// cs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/assets/ and the source repository is public at https://github.com/CAD97/xcode-ib-layout, with a commit for each finished step. Preparing the project Create a new Xcode project. We’ll use a iOS Single View Application template. The other settings don’t matter for this — we don’t have to write any custom code for this! Our demo will only use the portrait orientation of the iOS device, so feel free to disable landscape mode in the project settings. However, it will support both iPad and iPhone form factors, so make sure that the Devices target is Universal. To add the image assets, open your Assets.xcassets and drag the files to the white space below the AppIcon placeholder. Creating our background To create our background, we will use a Vertical Stack View. Drag a Vertical Stack View inside the default View in your main storyboard. Our background is three equally sized vertical chunks, so under the Attributes Inspector , set the Stack View’s Distribution to “Fill Equally”. For our own benefit, we will call this the “Background Stack” — to tell

Transcript of Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB...

Page 1: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �1 8 By Christopher Durham

Xcode 9 Interface Builder Layout By Christopher DurhamWhy? macOS and iOS devices come in many different screen sizes and aspect ratios. By utilizing the tools that Interface Builder gives you, it’s possible to write interfaces that gracefully adapt to many different screen sizes.

Resources All sources and assets used in this tutorial can be found at http://cs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/. The raw image assets are at http://cs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/assets/ and the source repository is public at https://github.com/CAD97/xcode-ib-layout, with a commit for each finished step.

Preparing the project Create a new Xcode project. We’ll use a iOS Single View Application template. The other settings don’t matter for this — we don’t have to write any custom code for this!

Our demo will only use the portrait orientation of the iOS device, so feel free to disable landscape mode in the project settings. However, it will support both iPad and iPhone form factors, so make sure that the Devices target is Universal.

To add the image assets, open your Assets.xcassets and drag the files to the white space below the AppIcon placeholder.

Creating our background To create our background, we will use a Vertical Stack View. Drag a Vertical Stack View inside the default View in your main storyboard. Our background is three equally sized vertical chunks, so under the Attributes Inspector � , set the Stack View’s Distribution to “Fill Equally”. For our own benefit, we will call this the “Background Stack” — to tell

Page 2: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �2 8 By Christopher Durham

Xcode to use this name as well, select the Identity Inspector � and set Document>Label to that name.

Our first task is to make the Background Stack the same size as the screen View. Note that we want this to be to the actual View itself, and not its Safe Area, as we want our background to extend to the edge of the screen, including past the iPhone X’s notch and under the status bar. To do this, we will utilize Constraints.

If it isn’t already, select the Background Stack and then click Add New Constraints � below the preview. Then we want to constrain the Background Stack to have 0pt spacing to its parent. Make sure “Constrain to margins” is not selected so that it will extend to the edge of the screen without regard for the “safe for UI” space.

To our Background Stack, two regular Views, and an Image View. We will call these “Background Top”, “Background Middle”, and “Background Bottom” respectively, so feel free to rename them in Xcode now. The bottom image is the simplest, so we start with that one.

Select the Background Bottom UIImageView, then in the Attributes Inspector � change the Image to be Purple Bottom image. The source image vector PDF is large enough that we can get the desired aspect without risking gaps simply by changing the View>Content Mode to be Top Left. This aligns the content of the view to the top left of the view, which in this case allows the overlarge image to overflow past the right and bottom of the view and get clipped to the appropriate size. This should work on all device shapes and sizes with the same angle reaching up to one third of the way up the screen, so feel free to change between different device previews and preview the behavior. When doing pure-IB layouts, it is recommended to check multiple screen shapes and sizes regularly to make sure that you get the results that you want.

Next we will tackle the top flair, which is a bit more complicated due to the required alignment to behave in a sensible way across different screen ratios. Add an Image View to the Background Top view and set its image to Purple Top. To make sure that the image remains at the correct aspect, control-drag from the image to itself and select the Aspect Ratio. This will lock in the aspect ratio of 15:8 (which is close enough to the inherent aspect — the actual image is 1537 × 886 which is an uneducable ratio).

Page 3: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �3 8 By Christopher Durham

Note now that the Interface Builder is presenting a warning � that something is wrong with our constraints. Clicking on that arrow or the project warning � will reveal the problem — our constraints are ambiguous to where Purple Top should be placed, and IB is asking for constraints for X and Y position. For the Y position, open up Add New Constraints � and add a 0pt spacing to the lower border. (Don’t worry about how IB places things until you’re finished constraining them — the large shift in size you see is normal.) For the X position, control-drag from Purple Top to Background Top and select to center the view horizontally.

Now, you should be able to see the problem here: IB has decided to make our image full-size, which distorts the small stripe we’re supposed to have to a large swath on smaller screens. To solve this, we will use a constraint to the top position. Select Purple Top again, Add New Constraints � for a 0pt top spacing to container.

At this point, a short detour for issue resolution. Switching to the iPhone X preview, we can see that our Purple Top does not extend up past the notch. If you select the Background Stack, you will see why — the Background Stack doesn’t either. Switch to the Size Inspector � and why should become evident. Under the Constraints panel, we can see that our Background Stack is constrained to the Safe Area instead of the Superview. Double click on each constraint here and change it to refer to the Superview instead of the Safe Area with a Constant of 0, and this should no longer be an issue.

Switching to an iPad, we can see the second issue. At these large sizes, IB doesn’t extend the top banner to the edges of the screen while the top, bottom, and aspect are bound as they are. Fixing this will require telling IB something different. First, Add New Constraints � for leading and trailing space. The default values are fine for now. In order to get IB to behave how we want, we need to tell it that it’s OK to fail to satisfy our top bound. Select the Top Space constraint in the Size Inspector � and change the Priority to a value less than 1000, such as 990. When IB is unable to satisfy all of your constraints, it acquiesces on the lowest-priority constraints first. Additionally, change the Leading and Trailing constraints to be ⩽0: we don’t care about exact alignment, only that the image extends beyond the edges of the screen. Our top flair should now behave in a sane manner across all portrait-mode iOS devices.

Page 4: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �4 8 By Christopher Durham

Now all that remains is the background color and a translucent paladin to fill space. For the background color, select the base View’s Attributes Inspector � and change its background color to CMYK 20/17/5/0. Notice that only a small bit of the screen actually changes color; the Background Top and Background Middle Views are currently marked as opaque. Select them and change their background to the top option “Default”, or effectively transparent. To add our paladin, drag a UIImageView onto the Background Middle, assign it the paladin-5e image, then constrain its aspect ratio to 35:44. The aspect ratio constraint can be changed by editing the constraint on the view’s Size Inspector � . Then we’ll Add New Constraints � of 0pt for above, trailing, and below, and in the Attributes Inspector � change the alpha to taste, somewhere around 0.2.

With this we’ve successfully created a responsive background that behaves sensibly on all of the iOS device’s portrait presentations — try it out! Landscape is different enough that it would require reflowing of elements, which we here defer to a more advanced tutorial, as it’s not reasonably possible solely through IB’s constraints.

Header Next, we will put the header text on top of the top flair. Now that the entire background is covered in views, it will be more necessary to drag to the hierarchy on the left of the preview in order to place new views where desired. For the header text, we will start with a Vertical Stack View below the Background Stack in the hierarchy. By

Page 5: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �5 8 By Christopher Durham

placing it below in the hierarchy, it is rendered above the background so that we can see it on top of the background. If it ends up in the stack instead of below it in the hierarchy, grab and drag it again. Moving left and right will influence whether it goes inside or outside a container, as indicated by the blue pin indicator. I will refer to it as the “Header Stack”. This stack should also be set to a Fill Equally distribution.

To position the Header Stack, control-drag from it to the base View and align its Top, Leading, and Trailing Space to Safe Area. Then, drag from the Header Stack to the Background Top to align their Bottoms. This should achieve that the Header Stack gets out of the way of the top unsafe space, but aligns its bottom with the bottom of the top flair.

Add a label to the Header Stack that says “FURMAN”, and set its font to a UltraLight Helvetica Neue in White. To get an appropriate size across devices, set the font size to 300pt, but also set the Autoshrink to a Minimum Font Size

somewhere around 12. As the text’s width will be that of the device, it should never get that small. Importantly, make sure that the Baseline is set to Align Centers in the Attributes Inspector � .

Below the FURMAN label, add a Horizontal Stack View, also set to Fill Equally. To it, add two spacing views with transparent backgrounds. Add a UNIVERSITY label to the second view, and set it to a white UltraLight Helvetica Neue as well. Add New Constraints � of 0pt above, before, and trailing the UNIVERSITY label. Set its font size somewhere around 150 and its Autoshrink Minimum Font Size to 12. To get the label text to align to the top of its bounding box, switch the Baseline to None. The header text should now comfortably stay within the top flair on all portrait iOS devices.

Page 6: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �6 8 By Christopher Durham

Bottom Text Below the Header Stack, add a Horizontal Stack View, which I will call the Bottom Text Stack. Just like all the others, it should be set to distribute evenly. Add New Constraints � to this view for leading, trailing, and bottom, at 0pt. To the stack, add two labels. Both should be set to a white Helvetica Neue at around 100pt and set to auto shrink down to 12pt. The left should be set to a date and the right to an ID number, the former left-aligned and the later right-aligned. Due to limitations on Autoshrink, the best way to get both labels to shrink to a similar font size is to add spaces in the middle to the shorter such that they appear the same size. For the example of 05/08/1997 — 1008974, four spaces before the ID number suffice.

Selecting the labels, you should be able to see that their bounding boxes are much taller than they should need to be for their current size when on smaller screens. This is a limitation of Autoshrink that we worked around by using overflow rules and baseline alignment for the header. Simplified, the reason for this is that the desired size of the label is calculated from the given desired font size, then is constrained by its

environment and any constraints that you put on it, and then Autoshrink scales the font to fit in the bounding box. The chosen font size does not feed back into the bounding box, so we get overtall bounding boxes in this case. In this case,

we work around this by constraining the aspect ratio to a reasonable ratio. Switch to the largest device, the iPad Pro 12.9” in the preview. If you used a 100pt font, you should find that the label’s bounding boxes fit rather snugly in this size. So, control-drag from each label to itself and constrain its aspect ratio to what it currently is

(this should be around 128:29). Set the Bottom Text Stack’s Alignment to Bottom and the labels’ to Align Centers, and you should be able to switch back to iPhone sizes with sane results.

Above the Bottom Text Stack but below the Header Stack, we will add one more label. Control-drag from it to the Bottom Text

Stack and select Vertical Baseline Standard Spacing. This will give a small standard amount of breathing room between it and the bottom stack. Add New Constraints � for

it with 0pt leading and trailing space.

Page 7: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �7 8 By Christopher Durham

Before you lose it on the dark background change it to a white 100pt Helvetica Neue with a minimum Autoshrink of 12pt as well. Set it to your name, and our bottom information should be finished!

Final Touches There’s one last final step to making our ID badge — the picture! Add a UIImageView between the Header Stack and the name label in the view hierarchy and set its image to the face image. Control-drag from it to itself to constrain its aspect ratio and set the ratio to 7:10. Drag from the image to the base view to set the leading space to 0pt, and from it to the top and bottom background to align its top and bottom. You should get the profile picture the height of your display and overflowing to the right; now go to its Size Inspector � to edit its constraints. Change the Top Align and Bottom Align from referring to the top and bottom to the bottom and top, respectively, of their respective background pieces. This should align the ID photo within the center of the screen.

And we’re done! The final layout uses no custom code — so you can use it as a startup screen! — and scales to all portrait mode iOS devices. The techniques used to build this should extend to most other UIs. Design your UIs early to support this kind of relative constraint-based specification; using IB to lay out your UI elements is much easier than doing so in code, and allows for easier modification down the line, and a solid understanding of the behavior of the constraint solver that IB uses will allow you to express many powerful UIs that adapt to different screen sizes.

Page 8: Xcode 9 IB Layout - Furman Universitycs.furman.edu/~cdurham/tutorials/Xcode9-IB-layout/Xcode 9 IB Layout.pdf · Xcode 9 IB Layout Tutorial Page 5 of 8 By Christopher Durham placing

Xcode 9 IB Layout Tutorial Page � of �8 8 By Christopher Durham