Initialization process of a view loaded from a storyboard

There are several ways to add view to a view controller. You can put it in
storyboard or you can create it in code and add as subview of view controller’s
view.

I sat down and spent some time on debugging, trying to maybe find something
useful and to learn about entire process of creating and presenting view.
And here are my findings.

View without subviews loaded from a storyboard

Let’s say there is a storyboard which has one view controller, and in the view
controller there is a view which is of some subclass of UIControl, and has
some constraints set, and has few IBInspectable properties defined so the
properties will be loaded and set after our view is loaded.

Here is how the flow look like:

I thought here will be some magic but didn’t find any. There are two or three
private methods called between public ones but do nothing special.

At first initWithCoder: is called and next is setNeedsDisplay.

All constraints of this view are set by calling addConstraints:. Here are set
constraints that not determine position of a view in its superview. So, only like
height and width. I thought that all constraints are set here but makes more
sense that not all are set in here, because position of this view is important
for its superview. When view has subviews, constraints that define position of
subviews will be added to the view that contains these subviews.

Next called method is awakeAfterUsingCoder: and view is prepared to be added
to superview because willMoveToSuperview: method is called and the next one
is didMoveToSuperview.

After view is added to superview awakeFromNib is called. I thought that awakeFromNib
is called right after awakeAfterUsingCoder even before adding view to its superview,
but was wrong. awakeFromNib is important method. This is a moment when you’ve
got your IBInspectable properties and key-value pairs defined in a storyboard
set and ready to use. Those loaded values are available before super awakeFromNib
is called. awakeFromNib is called by UINib’s instantiateWithOwner:options:
method, so it loads the view, decodes and set properties and those are ready to be used.

Next willMoveToWindow and didMoveToWindow methods are called. I was a bit
confused why those are called (because view is added to its superview, not to a window directly)
but read documentation which says that default implementation of these
methods do nothing and this is useful if you want to do additional things
when view moves to another window.

When view is on screen the updateConstraints:, layoutSublayersOfLayer: and
layoutSubviews: methods are called. That’s all for this case. Easy to remember.

View with subviews loaded from a storyboard

The flow is bit different because there are few subviews to add and layout.

First difference is that after initWithCoder: method is called the next one
is adding subviews of this loaded view in _addSubviews:positioned:relativeTo: method.
Other things to time when updateConstraints method is called stays the same.
The second thing is, no matter how many views there are the setNeedsLayout method is
called twice and layoutSublayersOfLayer: is also called twice.