This is the first part of tutorial aimed at increasing comfort level with auto layout as its all about how well you understand auto layout. First thing about auto layout is,either you hate it or you love it,there is no scope for ignoring it. Auto layout is not a new kid in the block it is well established and it will either bully you or be your friend choice is yours. The tutorial is aimed at understanding auto layout and communicating auto layout. I have divided the tutorial in two parts
By the end of tutorial you will have a basic understanding of what auto layout is and how it works.
1.Basics (What is auto layout).
Autolayout is visual layout system based on Cassowary. The idea is to view the UI as a set of equalities and inequalities which can be satisfied to a conclusion. Auto layout allows you define a set of constrains which are solved to a optimal solution.Example of the same could be “View “A” will always be in Vertical Center”.A deeper discussion on visual layout system is out of scope for this part of tutorial as we proceed further we will discuss in details the followings
Further after we will be discussing
2.Being relative and yet unambiguous (Ambiguity explained.)
Lets start with our first example “View “A” will always be in Vertical Center” ,and lets see what we can make out of it.To start with this statement is a valid constrain but it is just one of the valid constrains required.If we tell auto layout system that “View “A” will always be in Vertical Center” auto layout will throw a set of questions on us for example
- What is height of view A?
- What is width of view A?
- What is its position Horizontally?
Simply put information incomplete.Which means we have ambiguity.If you are using Interface Builder the you will get warning yellow mark or red marked errors depending upon the severity of the ambiguity.
Once I click on the red arrow I can see more specific details about what went wrong.
Lets read and make sense from top to bottom of the warnings one by one
- Missing Constraints : View A Needs Constraints for: X or Width:- First thing about auto layout is ,They ignore or over rule frame information completely.Here what happened that I have given the constraint about the position of center of View A. But the provided constraint cannot be used to evaluate view’s width or X value.
- Missing Constraints : View A Needs Constraints for: Y or Height:- Here what happened that we have given the constraint about the position of center of View A. But the provided constraint cannot be used to evaluate view’s height or Y value.
- Misplaced Views : Expected :x=0 ,y=300, width=0,Height: 0
Actual:x=198 y=41 ,width=282,height= 348 :- These types of warning show that the constraints are not in agreement with the actual placement on Interface Builder and the result will be according to Autolayout and you will not get WYSIWYG results.
In case of View A since we have not given any height width information so they will evaluate to 0 respectively.Since our view is reduced to a point with zero width and height it will be pushed down to y=300 the only constrain we provided.X will also be 0 as we have not given any information.We will solve these issues later in the tutorial.
Ambiguity can also arise due to conflicting constrains i.e there is disagreement between two or more given constraints.Lets pin the following constraints as in screenshot given below.
This will result into following errors and warnings. here we get a list of conflicting constraints which cannot be mutually satisfied.
- Center Y Alignment -View – View A
- Vertical Space (21)- View A – Top Layout Guide
- Vertical Space (211)-Bottom Layout Guide – View A
Lets make sense of the given conflicts .Autolayout is just trying to tell me that it is having trouble understanding me and it determine what i want.First i say view will be vertically Center aligned.Ok thats fine but then i say it will be 21 space from top and 211 space from bottom which do not agree with vertical center constraint. Since autolayout wont take decisions on our behalf in this case it throws error.
Above we saw two simple and basic cases of missing and conflicting constrains.In real life you will have more complex view hierarchy and conflicts but the base understanding remains same.Once errors start making sense you wont be making many.
PRO TIP:- Never make your view as a big structure ,create basic views and inside them, create further detailed views.For example you can divide your LOGIN view in three section top middle and bottom.Top will have logo bottom will have submit button and middle one will have text field necessary. So you will have a drilled down capability while applying auto layouts.
3.Example (A walk through to a simple UI Using auto layout )
For the walk through we will create a UI element which will have a image as a prefix to UILabel and the total length of image+ text will be in relative center of the paren view.We will try to clear out following concepts in the walk through
1.UILabel and its intrinsic size based upon its content.
2.Creating a view with its intrinsic size dependent on its subviews.
3.Revision of ambiguity concept which we discussed above.
4.Constraint priority and their partial usage
Lets get started.
Problem Statement :- We have to create a view which will have a image prefix to a text. text could be of variable length.We have to achieve a result where in Image + text is always in center of a parent view. For simplicity we will have a simple UI with following result
Step 1: First create a single view project and name it something of your choice and open the story board fist view.Drag a view with some reasonable size and set its background color to yellow.I have resized my viewcontroller to 3.5″.The resultant view should look some thing like this
Step 2: Now we will add constraints to the yellow view .To begin with we will add width and height constraints (Wait a minute didn’t we say that view will have dynamic width?Ok we will get back to it later) Add the following constraints as per the image below do not bother with width value any value will do just fine for width just keep it large enough so that we can add autolayouts properly.
After adding these two constraints you will see that XCode is giving you errors as in below image lets see them and understand them.
We have two errors (red means error)As discussed above lets revisit the ambiguity part
- Missing Constraints : Need constraints for : X position :- As discussed above we have given the view a width and a height so its “BOUNDS” is defined but we have not given its origin so its “FRAME” is not defined. Autolayout is not able to determine what will be the X position of our yellow view
- Missing Constraints : Need constraints for : Y position :- As discussed above we have given the view a width and a height so its “BOUNDS” is defined but we have not given its origin so its “FRAME” is not defined. Autolayout is not able to determine what will be the Y position of our yellow view
To solve this we have to give autolayout some thing to resole X and Y. Since we cannot set frames we will do it autolayout way.Add following constraints as per the image given below I will explain it later.
What we have done is,We have added a “Vertical Center” and “Horizontal Center” these constrain tell autolayout that our yellow view will always be in center Horizontally: so X in determined same is with vertical constraint and Y is determined.(you might have to adjust frame).
Step 3: By now our base yellow view is ready. We will add the prefix image as subview of our yellow view with following constraints.You can choose any image of your choice.
Since we have fixed dimension for our prefix image we will have fixed width height for this imageview. Add the constraints and proceed to next step.
Step4: Add a UILabel as the sub view of our yellow view and add following constraints
As you can see i have given only relative constraints to our UILabel.Its 8 points from prefix image and 0,0,0 top trailing and bottom from yellow view.Since we want the width to be dynamic we will not give width or height constraints.
Q: Why we are not getting any errors now , we have not given any width and height?
Ans:- We get error or warning only when auto layout is not able to resolve any thing which is must to render a view on screen.Be it height width or origin.Since our label is relative to yellow view and prefix image and their frames is well defined autolayout is able to calculate the frame of our Label.
Step 5: Now if we recall we will realize that we have given fixed view to out yellow view but we want it to be dynamic dependent upon the text of our label.So We will modify our Width Constraint of yellow view.Width of yellow view is necessary to resolve ambiguity but we want it to be overruled at runtime based upon the content of UILabel. So we will select our yellow view and go to Size inspector and reduce the priority of width constraint to 1 so that it will be over ruled. Follow the image given below.
Step 6: We want out UILabel to expand according to text and push our yellow view.So we have reduced the priority of yellow view width.Now we will increase the priority of text compression resistance of our UILabel.We want our view to reduce as well so we will increase the priority of content hugging of UILabel.Follow the image below
As you can see we have increased content hugging priority to 500 and compression resistance priority to 751 which will successfully over rule the width constraint’s 1 priority.
Now build and run you will see some thing as following.
Thanks for following give feedback in comments.