Understanding UIKit’s View display lifecycle
Problem:
Let’s start with an example of why it’s important to know.
UIImageView
This is an explanation of the problem I was trying to make a circle of imageview. (Note: I only get this problem if I'm using AutoLayout
.)
I tried to circle in following code
In this code, ImageView
the following constraints are set in.
1. ImageView
Put 200 at the top of the super view
2. Place the ImgaeView
left edge of the super view at 147pt from the left edge of the super view
3. Place ImageView
the right edge of the super view at -147pt from the right edge of the super view
4. ImageView
Height With width
If you do not know how AutoLayout
engine calculate the UI frame than should read this: AutoLayout Engine. After running this program I observed that this code has a strange shape instead of a circle. After investigations a lot of things, I noticed that it was due to the timing of executing the following code.
we are trying to the shape of the circle by setting to half of its height (or width). The reason why it becomes a strange shape instead of the circle is in the life cycle of UIViewController.
UIViewController life cycle:
Many methods are executed in order from the transition to ViewController until the View is displayed.
loadView()
The view controlled by the controller is created at the timing of loadView. Override this function when creating View by code without using xib or storyboard. also, make sure that loadView should not be overridden when using StoryBoard or xib.
viewDidLoad
This method called when the view controller has loaded its view hierarchy into memory.
As mentioned above, if you are using Interface Builder(Storyboard or xib), the subview setup is generally done here.
viewWillAppear, viewDidAppear :
This method also now as Display system life cycle method. viewWillAppear: Is Called when the view is about to made visible. viewDidAppear Is called when the transition is complete and view displayed on the screen.
viewWillDisappear, viewDidDisappear:
This method is also known as the Hidden system life cycle method. viewWillDisappear: Is called when the view is about to make disappear. viewDidDisappear: Is called when the transition is complete and view no longer visible on the screen.
Note: calling viewDidDisappear that does not mean that the
viewControlle
object is destroyed.
viewWillLayoutSubviews, viewDidLayoutSubviews
These methods are the Layout-based life cycle method. In order to understand these UIView
movements, it is necessary to understand theUIView
layout process, so we will summarize them.
Layout life cycle in UIView:
It consists of the following three steps.
- Update constraint
- Frame update
- Rendering
1. Update constraint
Under the following conditions, when View constraint is changed, UIView
class updateConstraints()
is called and constraint is recalculated. Constraint updates are called from subview to superview.
- Enable/disable by an active flag of constraint
- Change priority of constraint
- Add/remove constraints
- Change the hierarchy of the view with constraints
When updating constraints explicitly
updateConstraintsIfNeeded()
setNeedsUpdateConstraints()
2. Frame update
layoutSubviews()
Is Called when the constraint is updated to update the frame of view and its subviews. The layout can be updated without blocking the main thread. Since it is updated from top-down (parent view → child view), updating the layout of the parent view will cause it to be updated recursively, causing a crash.
When updating the frame explicitly
layoutIfNeeded()
setNeedsLayout()
3. Rendering
When the frame information is updated, it is rendered for display on the display and drawRect_:
is called. In this drawing step, you will draw using Core Graphics. Under the following conditions, drawRect_:
is called and redrawing is performed.
- Moving/deleting another view that hides part of it
- Re-displaying a view that was hidden
- Scroll view off-screen and back on screen
- Of view
setNeedsDisplay()
,setNeedsDisplayInRect(_:)
of an explicit call.
The life cycle based on this is as follows.
Let’s take a look at the previous code again.
The imageViewcornerRadius
code to set up. but you have to get the height of imageView which is determined or calculated in layoutSubviews()
the method. So, Instead of writing the above code inviewDidLoad
or viewWillApper
put it in viewDidLayoutSubviews
method.
If you like this post, please share and give claps so others can find it 👏👏
You can follow me on Medium for updated articles. Also, connect with me on LinkedIn, Twitter.
If you have any comments, questions, or recommendations, feel free to post them in the comment section below!👇