Every view in view hierarchy need to have size(width and height) and position(x and y).
You have 3 option to set size and position for view in iOS.
- You can directly setting the frame of a view.
- Adding dynamism with Autoresizing mask.
- Positioning a view with AutoLayout
Setting the frame of a view:-
Frame of a view is a rectangular with position x-y coordinates and size with width and height. It can be set by
CGRect(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat)
e.g: view.frame = CGRect(x: 10, y: 10, width: 50, height: 10)
- Fine-grained control
- You define the frame so it’s easier for you to know how your interface look like.
- You need to set frame of every view
- Update frames with every change like rotate, transfer, screen size is difficult
- Complex solution
Adding dynamism with Autoresizing mask:-
- An integer bit mask that determines how the receiver resizes itself when its superview’s bounds change. When a view’s bounds change, that view automatically resizes its subviews according to each subview’s autoresizing mask.
- The default value of this property is
none, which indicates that the view should not be resized at all.
- e.g: view.autoresizingMask = [.flexibleWidth, .flexibleHeight].
- It will provide flexibility and dynamism
- It has limited options
- Cannot compete with auto layout
Positioning a view with AutoLayout:-
Instead of setting framework directly, autolayout uses constraints to describes relationships between views. As a result it helps in dynamic layout and user interface respond to any internal and external changes can be handled with minimal effort
e.g: button.widthAnchor.constraint(equalToConstant: 100).isActive = true
- When application runs, autolayout engine inspects the constraints and infers the correct size and frame for each view in view hierarchy.
- If any internal and external changes like device orientation, autolayout engine invalidate the layout. Then it inspects the constraints and infers the correct size and frame for each view in view hierarchy.
- It is descriptive and flexible
- It provides dynamic layout
What is Constrains?
- Constraints typically represent a relationship between two views.
- Autolayout engine inspects constraint and infers size and position of each view in view hierarchy.
Anatomy of a Constraint:-
- Layout of each view in view hierarchy is defined as a series of linear equation
- In Autolayout, attributes defines the feature that can be constrained.
Constraint Priorities and unsatisfied constraints:-
- By default all constraints are required.
- Auto Layout must calculate a solution that satisfies all the constraints. If it cannot, there is an error. autolayout prints information about the unsatisfiable constraints to the console.
- You can also create optional constraints. All constraints should have a priority between 1 and 1000.
- Try to give system defined priorities i.e 250 -low priority, 500-medium, 750 -high priority, 1000-required priority.
Intrinsic Content Size:-
- You need to provide position and size for each view in view hierarchy to set frame for that view. However, some views have a natural size given their current content. This is referred to as their intrinsic content size
- Intrinsic content size can define view’s width or height or both.
e.g1: A label or button’s intrinsic content size is based on the amount of text shown and the font used.
e.g2: An empty image view does not have an intrinsic content size. As soon as you add an image, image view intrinsic content size is set to the image’s size
e.g3: Textview with scrolling enabled does not have an intrinsic content size. Textview with scrolling disabled, by default the view’s intrinsic content size is calculated based on the size of the text without any line wrapping.
How Autolayout represent view’s intrinsic content size?
Autolayout represents a view’s intrinsic content size using
content hugging and
compression resistance constraints.
- The content hugging pulls the view inward so that view fits around the content.
- By default, views use a 250 priority for their content hugging.
- Setting a larger value to this priority indicates that we don’t want the view to grow larger than its content.
- e.g: Consider two views placed horizontally with no proper constraints for width. This will create a conflict. In this situation we need to set horizontal content hugging priority of one view greater than that of the other. View which has horizontal content hugging priority less will grow and the view with greater priority one will stick to its intrinsic content size.
- The compression resistance pushes the view outward so that it does not clip the content.
- Setting a higher value means that we don’t want the view to shrink smaller than the intrinsic content size
e.g: Consider button with large text and assign the width constraint of 10points.
To solve this problem set compression resistance priority to 1000 and width priority to 750.
Intrinsic Content Size Versus Fitting Size:-
- The intrinsic content size acts as an input to Auto Layout.
- When a view has an intrinsic content size, the system generates constraints to represent that size and the constraints are used to calculate the layout.
- The fitting size, on the other hand, is an output from the Auto Layout engine.
- Fitting size is the size calculated for a view based on the view’s constraints.
- If the view lays out its subviews using Auto Layout, then the system may be able to calculate a fitting size for the view based on its content.
- Stack view is good example for the fitting size. You can create a valid layout using only a single vertical and a single horizontal constraint to define its position. But its size is calculated by Auto Layout.
- Setting the stack view’s content hugging and compression resistance (CHCR)priorities has no effect, because the stack view does not have an intrinsic content size.
- If you need to adjust the stack view’s fitting size relative to items outside the stack view, either you need to create explicit constraints to capture that relation or add CHCR priorities to stackview’s contents.
How do we implement Auto-Layout?
- We can do it programmatically, with NSLayoutAnchor or Visual Format Language
- We can do it visually, with Interface Builder (IB) and Storyboards
- We can even take a non-native approach with third-party kits.
Autolayout in xib/storyboard:-
Steps for adding Autolayout in xib/storyboard
- Create a view
- Select view and add required constraints from the options provided.
Each button has its own function:
- Align — Create alignment constraints, such as aligning the left edges of two views.
- Add new constraints — Create spacing constraints, such as defining the width, height, leading, trailing, top and bottom constraints
- Embed in — Embed views into a stack view (or other views).
- Resolve auto layout issues — Resolve layout issues.
- Update frames — Update the frame’s position and size in reference to the given layout constraints.
This can be achieved by two way
- Creating constraints using Visual Format Language
- Creating constraints using Anchors
Visual Format Language:-
VFL is old technique for setting constraints but still it is in use. To know more about VFL click here:
- Starting with macOS 10.11 and iOS 9, there was
NSLayoutAnchorthat simplifies Auto Layout.
- Auto Layout anchors are by far the easiest way to make constraints.
child.widthAnchor.constraint(equalToConstant: 200).isActive = true
- A Boolean value that determines whether the view’s autoresizing mask is translated into Auto Layout constraints.
- Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts.
- If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to
view.translatesAutoresizingMaskIntoConstraints = false.
- We should never mix resizing masks and Auto Layout.
translatesAutoresizingMaskIntoConstraintsproperty is false by default for views from xib or storyboard.
translatesAutoresizingMaskIntoConstraintsis true if we declare layout in code. The intention is for the system to create a set of constraints that duplicate the behaviour specified by the view’s autoresizing mask.
Thanks for reading! I hope y’all are staying safe at this time. Just want to say hi — feel free to leave a comment! and hit the clap button below 👏 to help others find it!. follow me on Medium.