In iOS, What's the Difference Between Autoresizing, Autolayout, and Constraints

In iOS, what's the difference between autoresizing, AutoLayout, and constraints?

There are really just two things here:

  • Autoresizing
  • AutoLayout

Autoresizing is basically a collective term for the old way Apple introduced in order to enable developers to build dynamic layouts. The number one usecase to address here was screen rotation. Since when a screen would be rotated (or otherwise resized), the subviews in the screen would most likely hold an incorrect frame (position and size) in the newly sized superview. To address this, Apple introduced a series of enumerable properties (called Autoresizing Masks), that tell the superview to treat a subview in a particular way. Among these are:

  • Flexible Width/Height, which causes a subview to expand to the fullest width/height available

  • Flexible Leading/Trailing/Top/Bottom space, which allows a specific edge to be variable, and so forth.

A view could contain any combination of these enum properties.

This was inadequate because, among other shortcomings, it lays down no rules regarding how a view should be layouted (if that's a verb) with respect to its other sibling views. It also required a lot of extra coding to manually resize views on orientation changes.

Here's where AutoLayout entered the picture. Apple built a framework which worked on the basis of constraints - rules that could be applied on views and between views, that would determine how a view would be sized in variable screen sizes. These constraints are structured in a class called NSLayoutConstraint, and each instance (constraint) of this class has the following important properties:

  • The item (view) on which the constraint is applied
  • The property of the view (height, width, leading edge, trailing edge, and so on) that the constraint is applicable to
  • The second item (a sibling or a child or a parent view) to which the constraint is related
  • The second item's attribute
  • The multiplier on the constraint: useful in order to specify ratio based constraints
  • A value (or constant) of the constraint: interestingly, the only property of a constraint that can be changed after instantiation.

A simple example of an NSLayoutConstraint, stated prosaically is: a view's width will be half the the width of its superview multiplied by 60%.

Your AutoLayout based UI would consist of many such constraints, which will all work together to express an unambiguous and non-conflicting UI Layout.

Now the AutoLayout engine, which makes it all work, interacts with views on the screen, calling AutoLayout messages such as layoutSubviews whenever needed in order automatically resize (layout) views whenever changes occur on screen, such as orientation change, a superview getting resized etc.

Constraints are most commonly added by InterfaceBuilder (.xib and .storyboard files), but adding them by code entails the same principle: create an instance of NSLayoutConstraint and add it to the highest view applicable (for eg., if there's a constraint between a child and a parent view, the constraint should be added to the parent view. If there's a constraint between two subviews, again, add it to the parent.)

Apple's AutoLayout guides, API documentation and introductory WWDC videos on AutoLayout are excellent, and those would be the best places to learn more.

What is the basic difference between Auto Layout and Auto Resizing in iOS

As Matt Neuburg states in his book:

Autoresizing is a matter of conceptually assigning a subview “springs
and struts.” A spring can stretch; a strut can’t. Springs and struts
can be assigned internally or externally. Thus you can specify (using
internal springs and struts) whether and how the view can be resized,
and (using external springs and struts) whether and how the view can
be repositioned.

And

Autolayout, depends on the constraints of views. A constraint (an
instance of NSLayoutConstraint) is much more sophisticated than the
"autoresizingMask" it’s a full-fledged object with numeric values, and
can describe a relationship between any two views (not just a subview
and its superview).

Auto Layout(Constraints) Vs Auto resizing mask(Springs & Struts)

I had the same question when I started using auto layout...

Auto Layout can do all that Springs & Struts provides us and more.

Auto Layout can be applied to any two views depending on the need and not only to parent child view hierarchy like Springs & Struts.
we can give priority to constraints and have constraint inequalities.

Suggestion: when you start applying auto layout on views, first you should thoroughly analyze "How the views will behave for different scenarios" and then according to your needs apply constraints, the more you use it you come to know how difficult problems can be solved quite easily by auto layout.

Is it okay to mix autoresizing mask with autolayout?

As far as I am aware it is absolutely alright to use both autolayout and autoresizingmasks together. What you don't want to do is add autolayout constraints to a view that you are using autoresizing masks to govern layout. A general use case for autoresizing masks is adding a view to a view and wanting it to be pinned top, bottom,leading, and trailing. In that case it is simply

let pinnedToSuper = UIView(frame: self.view.bounds)
//all views default to .translatesAutoresizingMaskIntoConstraints if added programmatically
pinnedToSuper.autoresizingMask = [.flexibleWidth,.flexibleHeight]
self.view.addSubview(pinnedToSuper)

Notice how much easier this is as opposed to adding each constraint.

Prior to autolayout autoresizing masks were all iOS had to help with layout. Heads up autoresizing masks are also known as springs and struts. An example use case autoresizing masks break down is if you want a view to maintain a perfect square(or to make a circle) keeping aspect ratio and also resizing with the view in all orientations. In this case you would have to add code in layoutSubviews to resize the view manually based on parent bounds. You can see that this could get tedious especially if you are dodging views that are separately being handled by autolayout. This is probably why it is good to be careful when using both. I tend to use it in simple cases such as adding a view that sticks to the superviews bounds.

Important distinction when using together.

You should avoid trying to add autolayout constraints to a view that you are using autoresizing masks to attempt to blend them and achieve a layout because you will likely get conflicting constraints with no real effect. You can however add autolayout constraints to a view that has a subview that is being governed by autoresizing masks and there should not be any issues. This is my typical use case. I hope this helps you with how you might use it.

iOS: Auto Layout vs autoresizingMask - resizing whole view to fill?

To accomplish the same thing using constraints you need to set the leading, trailing, top and bottom space to the superview to 0. See below:

//load the ButtonGridViewController from a xib
[[NSBundle mainBundle] loadNibNamed:@"..." owner:self options:nil];

//get the view add it
[self.view addSubView:self.myGridView];

//turn off springs and struts
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];

//add constraints to fill parent view
NSArray *arr;

//horizontal constraints
arr = [NSLayoutConstraint constraintsWithVisualFormat:@"|[vw]|"
options:0
metrics:nil
views:@{@"vw":self.myGridView}];
[self.view addConstraints:arr];

//vertical constraints
arr = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[vw]|"
options:0
metrics:nil
views:@{@"vw":self.myGridView}];
[self.view addConstraints:arr];


Related Topics



Leave a reply



Submit