Learn about the initialization process of the two well known classes in UIKit. Say hello to UIViewcontroller, and UIView init patterns.
Actually UIViewController intialization is pretty straightforward. You only have to override a few methods if you want to be in full control. It depends on the circumstances which init will be called, if you are using a storyboard, init(coder) is the one that you are looking for. If you are trying to initiate your controller from an external nib file, init(nib,bundle) is going to be called. You also have a third option, you can initialize a controller programmatically from code. Long story short, in order to make a sane init process, you have to deal with all this stuff.
Let me introduce two patterns for UIViewControllers, the first one is just a common init function that gets called in every case that could initialize a controller.
You can also hide the init(nib,bundle) and init(coder) methods from the future subclasses. You don't have to override init(nib,bundle) and you can mark the init(coder) as a convenience initializer. It seems like a little bit hacky solution and I don't like it too much, but it does the job.
I usually create a common initializer for UIViews to make the init process more pleasant. I also set the translate autoresizing mask property to false in that initializer method, because it's 2017 and noone uses springs & struts anymore, right?
It's also nice to have some autolayout helpers, and if you want to initialize a view from a nib file, it's really good to have some convenience method around.
With the help of the snippets above, it's really easy to maintain a sane init process for all the UIKit classes, because most of them ared derived from these two "primary" classes. All the code above is part of the CoreKit framework, feel free to use it.