Updated over 3 years ago | GitHub

Custom Views Quickstart

Overview

The iOS framework comes with many views that cover common
user interface elements. You can also create a custom view to
encapsulate the visual appearance and behavior of your own reusable
component.

For example, in a news reading application we might want a standard
component to display images with a caption using a consistent style on
both the home page view controller as well as the individual story view
controller. This quickstart gives a recipe for making a custom view in
Interface Builder and using it in another part of your application.

Creating a Custom View

Step 1: Design custom view Interface Builder

Create a .xib file by selecting File -> New -> File... -> iOS -> User Interface -> View. Name your file something something descriptive like
CaptionableImageView. Open this file Interface Builder and start
designing your view by dragging in components from the Object Library.

Step 2: Create subclass of UIView

Create a subclass of UIView by selecting File -> New -> File... -> iOS -> Source -> Cocoa Touch Class. Normally you’ll want to name your
class to match your .xib file.

Step 3: Set custom class in Interface Builder

Open your .xib file and select the File's Owner object in the
Document Outline. Select the custom class of File's Owner to the
class you just created.

Step 4: Connect outlets

Open the Assistant Editor and pick your custom class. Create outlets
for anything you’ll need to manipulate or set programatically.

Step 5: Create outlet for content view

Create an outlet for the top-level view in your .xib and call it
contentView.

Step 6: Add initialization code

In the custom view class, you’ll need to override the initWithCoder and
initWithFrame methods to load the .xib and add the content
view to the view hierarchy.

class CaptionableImageView: UIView {
    ...
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initSubviews()
    }

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

    func initSubviews() {
        // standard initialization logic
        let nib = UINib(nibName: "CaptionableImageView", bundle: nil)
        nib.instantiateWithOwner(self, options: nil)
        contentView.frame = bounds
        addSubview(contentView)

        // custom initialization logic
        ...
    }
}

Step 7: Add code that allows configuration of your custom view

Finish adding the rest of the code for your custom class. You’ll want
to give users of this class a simple way to configure the elements of
the view without exposing them to uncessary details. For example, in our
CaptionableImageView we can provide more convenient ways to set the
image and caption.

class CaptionableImageView: UIView {

    @IBOutlet private var contentView: UIView!
    @IBOutlet private weak var label: UILabel!
    @IBOutlet private weak var imageView: UIImageView!

    var caption: String? {
        get { return label?.text }
        set { label.text = newValue }
    }

    var image: UIImage? {
        get { return imageView.image }
        set { imageView.image = newValue }
    }
    ...
}

Using a Custom View

Once you’ve finish your custom view you can now use it pretty much as
you would any other view.

Using a custom view in storyboards

Open up your story board and drag a View (colored orange below for
visibility) from the Object Library into your view controller. Set the
view’s custom class to your custom view’s class.

Create an outlet for the custom view in your view controller. A good
place to configure the view is in viewDidLoad.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: CaptionableImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        imageView.image = UIImage(named: "codepath_logo")
        imageView.caption = "CodePath starts new class for designers"
    }
}

Using a custom view programatically

To instantiate your view programatically, you can call initWithFrame
on your custom class. You’ll have to manually add it as subview.

class ViewController: UIViewController {

    var imageView: CaptionableImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // we'd probably want to set up constraints here in a real app
        imageView = CaptionableImageView(frame: CGRectMake(0, 20, view.bounds.width, 200))
        imageView.image = UIImage(named: "codepath_logo")
        imageView.caption = "CodePath starts new class for designers"
        view.addSubview(imageView)
    }
}

Further reading