A long time ago, in a galaxy far far away, Apple decided to create Interface Builder, a place to build interfaces
(you don’t say!) in an easy drag and drop way. To guarantee the same aspect to any screen size, it uses Auto Layout, a tool that gets rules applied to components and organizes them on the screen.
As a new developer, you’ve probably started creating iOS UIs using XIBs and Storyboards. It’s simple, it’s visual, it does its job. However, as time goes on, teams grow, projects get larger and more complex and our worst nightmare starts happening: XML conflicts.
You also probably have dealt with magic segues that are defined directly on storyboards,
@IBDesignable that don’t update, the macOS’s beach ball spinning for a long time when opening a storyboard, and OH MY GOD the “this class is not key value coding-compliant for the key <whatever>” error when you have a broken reference outlet.
Okay, done ranting. Let’s talk about how we can take advantage of Auto Layout without the pain of Interface Builder: using constraints, which are rules applied to components to define size, proportion, and position at a given screen related to other components.
A constraint defines the attributes (top, bottom, leading, trailing), the multiplier, the constant offset, and the relationship between components.
There are three main native ways to create views with code:
- Visual Format
As a bonus, there’s a very famous library to make your work easier and you code cleaner: Cartography.
I’m creating a very veeeeery simple layout with a label and a button. They have a space of 8 points to each other and 20 points to the superview.
To be able to use view coding, you’ll have to delete the
Main.storyboard and start the window manually. Follow this tutorial if needed. Then, create the components and call one of the setups below in the
This is probably the oldest and least used form, I have tried using it but the later options are way better. Despite that, I’m quickly gonna show you how it works. You can also access the original documentation here.
The orientation is defined with H (horizontal) and V (vertical), a dash (-) indicates the spacing, a pipe (|) indicates the superview, and the components are represented between square brackets ([button]).
The default space (-) is 8, adding a numerical value between dashes will create a custom space
For me, the worst part of Visual Format is the usage of strings to define a component. It’s so error-prone! But, if you really wanna deep dive into this method, try this tutorial at Ray Wenderlich’s blog.
I think this is the method I mostly used before I discovered Cartography and when I still programmed in ObjC.
It’s quite verbose but it’s really straightforward, you just define the parameters a constraint must have and to which component it’s related to.
Don’t forget that trailing parameters require a negative offset
NSLayoutAnchor is available since iOS 9, it has the same idea as NSLayoutConstraints but is way less verbose. You link anchors and activate them.
The same layout can be achieved with the following code lines.
Last, but not least, there’s the library Cartography. It’s very light and the rules representations have the best readability, in my opinion.
Relationships are defined with operators ==, >=, <= and offsets are defined with operators +/-.
Remember to add cocoapods to your project (pod init) and add the dependency. Then run cocoapods (pod install) and use the workspace created.
That’s it! 🚀
These are four ways to achieve the same layout using view coding. No more storyboards or XIBs, no conflicts on XMLs that are impossible to read. As one additional advantage, code reviewing this type of layout is much easier than checking Apple’s XML files.
Hope you start refactoring those IB screens you have in your project and come to the view code side of iOS development.
If you want to see the complete code, check the repo here.