As promised from a previous post (How to Use Auto Layout in XCode 6 for iOS 7 and 8 Development) that I will write another article related to more advanced techniques in AutoLayout to develop iOS mobile apps for iOS 7 and iOS 8.
In this article, I am going to share a few common layouts, scenarios and problems that I am facing when I am developing the iOS app using the Auto Layout. I am going to show the techniques to link different objects together using constraints inside the same view controller.
Auto Layout for iOS 8 versus iOS 7
I believe most iOS developers will still include iOS 7 under their development plan. So before getting started, it is good to know the differences between Autolayout in iOS 7 compare with iOS 8.
One of new things in iOS 8 is the Layout Margin. Layout Margin is a new property available in UIView for iOS 8. So, any objects inherit from UIView will have this property. If you are developing the app for both iOS 7 and iOS 8, you should not use Layout Margin (or use layout margin in a smart way).
So, if you have any constraints related to layout margin and you didn’t do a proper check before launching the app on iOS 7 devices, the app might crash or the arrangement of the objects might be out of order.
Whenever you are trying to add new constraints from the storyboard in XCode 6, “Constrain to Margins” is ticked by default as show as the screen shot below. The meaning of this selection is to add constraints with the new property in iOS 8.
If the deployment target of your app is iOS 7 and above and any of your constraints have this layout margin, the XCode will complain with the warning “Layout attributes relative to the layout margin on iOS prior to 8.0”.
If you are developing the app for both iOS 7 and 8, it is best to “Untick” the Constrain to Margins.
How to use Auto Layout with more than One Object
Using the autolayout constraints with more than one object inside the same view controller can be tricky.
You may ask yourself some questions when you are deciding the design before trying to link the objects together inside the view controller:-
1. How many objects are inside the view controller?
2. Is the object fixed in height or have flexible height?
3. Is the object fixed in width or have flexible width?
4. How would the object be positioned inside the view controller. (Eg: Stick on the top of the view controller)
5. What is the relationship between Object A and object B? (eg: The Object B is positioned on the Right of the Object A)
Example:-
Let’s say I have a view controller with 2 Text Fields (Email and Password) and one Login Button.
Here is my decision:-
1. Both the Text Fields have fixed height (50 px) but with flexible width.
2. There will be a Navigation Controller on the top of the View Controller.
Decision on EmailTextField
– The Top of the First Text Field (EmailTextField) will stick to the Top Layout Guide of the Navigation Controller
– The Left of the EmailTextField will stick to the Left Side of the Superview (Leading Space)
– The Right of the EmailTextField will stick to the Right Side of the Superview (Trailing Space)
So, there are 4 constraints that I will have to associate with this EmailTextField object. The below screen shot shows the 4 constraints:-
If you do it correctly, You will see 4 constraints on the Size Inspector and also the Document Outline like the screen shot below.
Next, I want to add the PasswordTextField onto the screen. I will position it on the bottom of the EmailTextField.
Decision on PasswordTextField
– The Top of the First Text Field (EmailTextField) will stick to the Bottom of the EmailTextField.
– The Left of the PasswordTextField will stick to the Left Side of the Superview.
– The Right of the PasswordTextField will stick to the Right Side of the Superview.
Here is screen shot for adding the constraints for the PasswordTextField.
If you do it correctly, you will see that the Top Space of the PasswordTextField is Linked to the Bottom Space of the EmailTextField like the screen shot below:-
IMPORTANT TIP: Double Click on the constraint on the Size Inspector to view the detailed relationship of the constraint.
Finally, let’s link the constraints for the last object – the login button.
Decision on the Login Button
– The button has fixed height: 60 px
– It will stick on the bottom of the view controller with constant: 20 px (distance)
– There will be constant 16 px on the Left and Right of the superview
The above auto layout guide for multiple objects inside the same view controller is very straight forward because the top objects (EmailTextField,PasswordTextField) does not have any relationship with the bottom object (Login Button).
The autolayout will become more complicated when you want to add a UIScrollView and links all the objects together.
How to use UIScrollView with Auto Layout
Using the Auto Layout with UIScrollView can be tricky. I personally having a tough time with ScrollView when I first started learning Auto Layout. After some trials and errors for a few weeks, I almost got it right.
The most basic rule of using ScrollView with Auto Layout is you will have to set up the constraints from the top of the ScrollView to the bottom of the Scrollview and from the left to the Right. You can not have any missing link neither the horizontal nor the vertical layout. Or else the XCode will complaint!
Let’s just use the same example as the above and we will add all the 3 objects inside the UIScrollView.
First of all, we will have to add the scrollview onto the empty View Controller inside the Storyboard. For my personal preference, I would stick the top of the ScrollView on the top layout guide and not under the UINavigationBar. Remember, the Scrollview will always have flexible height and flexible width.
If you do it correctly, you will see that the leading and the trailing space to the super view will be 0, the bottom space to the bottom layout guide is 0 and also the top space to the top layout guide would be 0 as well like screen shot below:-
Next, putting the 2 text fields and also the login button inside the scrollview. If I connect the constraints exactly like the first example that I showed above. The XCode will complaint. The reason is adding a scrollview will change the behaviour of the Autolayout.
The common complaints:
1. Frame for “XXX” will be different during run time.
To Solve it: Add another constraint to align the object to the center of the superview (ScrollView)
2. The Views are vertically ambiguous or (Scroll View has Ambiguous scrollable content height)
To solve it: Link the objects from the top to the Bottom of the Scrollview (No missing relationship in the middle)
For the above case, I will make another constraint (Horizontal Center in Contrainer) to centrelize the EmailTextField. And then “Control Drag” to link up PasswordTextField with LoginButton with a vertical space.
The XCode will love you by adding the 2 extra constraints and stop complaining.
How to Resolve Conflict Constraints and Other Autolayout Errors/Warning
Here are some of the common AutoLayout Errors/Warnings:-
Warning #1: Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
Description: This only happens when your app has to support iOS 7 and the app have UILabel on one of your View Controller Objects inside the storyboard. And you didn’t tick “Explicit” on the “Preferred Width”.
How to Resolve this issue?
A. If you know where to locate the specific UILabel, just select the UILabel Object on the Storyboard. Then, Make sure that “Explicit” is ticked. If you do not want to have a fixed width, just assign the value as 0 (zero). The width for the UILabel will be based on the other connected constraints for this UILabel.
B. When your storyboard has many view controllers objects and also many UILabel, you may find it hard to locate the specific UILabel object. So, you will have to use the following steps in order to location the UILabel.
Resolve the Automatic Preferred Max Layout Width Warning From SourceCode
1. Right Click the Storyboard and “Open As” -> “Source Code”
2. Use the keyboard Key (Command + F) or Click “Find” -> “Find” on the Navigation bar of the XCode to launch the Search Window. Paste the code into the Find Window.
3. Click the Search Icon then Select “Edit Find Options”.
4. Then, Choose “Regular Expression”.
5. The Find Window will show you all the UILabel does not have preferred Layout Width. You will have to paste
preferredMaxLayoutWidth="0"
into all the UILabel like below screen shot until the count for the Find Window is 0.
6. Lastly, you will have to Open the Storyboard again. This time choose “Interface Builder – Storyboard”.
The above steps will solve all the Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0 warnings.
Warning #2: Frame for “xxx” will be different at run time.
Description: This warning is letting you know that the frame for the object inside the storyboard does not match with the constraints that you connected on that object.
How to Resolve this issue?
Most of the time, this issue can be solved easily by going to the “Resolve Auto Layout Issue” tab and choose either “Update Frames” or “Update Constraints”.
Sometimes, you may face a situation where the view controller has multiple Auto Layout Warnings. You may have already spend some time to fix the issue but the issue is too complicated that you might not be able to fix easily.
From my own experience in a situation like this, it is better to clear all the constraints for all the views inside the view controller. And then reconnect the constraints all over again for all the views. The chance is that after you reconnecting the constraints, you would not see the issue again.
“3. Is the object fixed in weight or have flexible weight?”
I think you mean “width” rather than ‘weight” right?
Thanks for pointing out. I just corrected it. 😉
can you pls., come with backward compatibility in adapting layout for iOS 6?
Sorry. I don’t have time for that. I already dropped the support for iOS 6 from all my projects for a very long time.
Why would you even want to optimize for iOS 6? Please take a look at the official iOS marketshare by Apple: appstore
On January 19, 2015:-
iOS 8: 69%
iOS 7: 28%
iOS 6 and Below: 3%
Why would you even spending time to optimize the app for less than 3% of the iOS users? Customer’s requirements? You should convince you customer to drop the support for iOS 6 as it is not worth the time at all.
This is a great tutorial for me to plays many tricks on autolayout thanks:)
Ricky, you have a logic bug here :
Decision on PasswordTextField
– The Top of the First Text Field (EmailTextField) will stick to the Bottom of the EmailTextField.
Shouldn’t it be
Decision on PasswordTextField
– The Top of the Second Text Field (PasswordTextField) will stick to the Bottom of the EmailTextField.
Good job!
Regards,
Eddy
waiterone.net
very nice tutorial……i have learn many things from this tutorial