· 2 min read

UIKit init patterns


Learn about the initialization process of the two well known classes in UIKit. Say hello to UIViewcontroller, and UIView init patterns.

UIViewController init

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.

import UIKit

class ViewController: UIViewController {

    override init(
        nibName nibNameOrNil: String?, 
        bundle nibBundleOrNil: Bundle?
    ) {
        super.init(
            nibName: nibNameOrNil, 
            bundle: nibBundleOrNil
        )

        self.initialize()
    }

    required init?(
        coder aDecoder: NSCoder
    ) {
        super.init(coder: aDecoder)

        self.initialize()
    }

    init() {
        super.init(nibName: nil, bundle: nil)

        self.initialize()
    }

    func initialize() {
        //do your stuff here
    }
}

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.

import UIKit

class ViewController: UIViewController {

    init() {
        super.init(nibName: nil, bundle: nil)

        self.initialize()
    }

    required convenience init?(coder aDecoder: NSCoder) {
        self.init(coder: aDecoder)

        self.initialize()
    }

    func initialize() {
        //do your stuff here
    }
}

class MyFutureViewController: ViewController {

    override init() {
        super.init()
    }
}
let vc = MyFutureViewController()

UIView init

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?

import UIKit

class View: UIView {

    init() {
        super.init(frame: .zero)

        self.initialize()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.initialize()
    }

    func initialize() {
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

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.

import UIKit

extension UIView {

    public convenience init(autolayout: Bool) {
        self.init(frame: .zero)

        self.translatesAutoresizingMaskIntoConstraints = !autolayout
    }

    public static func create(autolayout: Bool = true) -> Self {
        let _self = self.init()
        let view  = _self as UIView
        view.translatesAutoresizingMaskIntoConstraints = !autolayout
        return _self
    }

    public static func createFromNib(
        owner: Any? = nil, 
        options: [AnyHashable: Any]? = nil
    ) -> UIView {
        return Bundle.main.loadNibNamed(
            String(describing: self), 
            owner: owner, 
            options: options
        )?.last as! UIView
    }
}
let view = UIView(autolayout: true)

Using these snippets, 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.

Related posts

· 8 min read

10 little UIKit tips you should know


In this article I've gathered my top 10 favorite modern UIKit tips that I'd definitely want to know before I start my next project.

· 5 min read

Building input forms for iOS apps


Learn how to build complex forms with my updated collection view view-model framework without the struggle using Swift.

· 5 min read

Custom UIView subclass from a xib file


Do you want to learn how to load a xib file to create a custom view object? Well, this UIKit tutorial is just for you written in Swift.

· 4 min read

Custom views, input forms and mistakes


Just a little advice about creating custom view programmatically and the truth about why form building with collection views sucks.

Practical Server Side Swift cover image

Get the Practical Server Side Swift book

Swift on the server is an amazing new opportunity to build fast, safe and scalable backend apps. Write your very first web-based application by using your favorite programming language. Learn how to build a modular blog engine using the latest version of the Vapor 4 framework. This book will help you to design and create modern APIs that'll allow you to share code between the server side and iOS. Start becoming a full-stack Swift developer.

Available on Gumroad