Custom UIView with XIB file is a very common practice in iOS Development. Custom UIView classes don’t contain XIB files when you create them. That’s why we have to make sure that we connect the XIB file the right way. I will show you two approaches of merging the custom UIView with XIB file:

UIView initialized as a Custom Class UIView initialized programmatically

At this point, you might be confused from the above-mentioned points, but soon it will all get clear. Just keep reading…

UIView initialized as a Custom Class

This approach is used when you want to add your custom UIView class directly from the Interface Builder of your UIViewController or UIView class.

Probably you have met some examples as the above image. I will show you now how to achieve this. This approach is very easy to use and keeps your code clean.

Create a Super Class

We will create a super class called NibView, which will handle everything about the XIB file merging. The power of creating a super class is in the reusability. You can make each UIView inherit from its super class.

import UIKit class NibView: UIView {

var view: UIView! override init(frame: CGRect) {

super.init(frame: frame)



// Setup view from .xib file

xibSetup()

}



required init?(coder aDecoder: NSCoder) {

super.init(coder: aDecoder)



// Setup view from .xib file

xibSetup()

}

} private extension NibView {



func xibSetup() {

backgroundColor = UIColor.clear

view = loadNib()

// use bounds not frame or it'll be offset

view.frame = bounds

// Adding custom subview on top of our view

addSubview(view)



view.translatesAutoresizingMaskIntoConstraints = false

addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[childView]|",

options: [],

metrics: nil,

views: ["childView": view]))

addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[childView]|",

options: [],

metrics: nil,

views: ["childView": view]))

}

}

The magic happens inside the xibSetup() function. We are making sure that the UIView will be as big as its superview by using NSLayoutConstraints.

Create the UIView Extension

For initializing the custom XIB file I have created a UIView extension called loadNib().

import UIKit extension UIView { /** Loads instance from nib with the same name. */

func loadNib() -> UIView {

let bundle = Bundle(for: type(of: self))

let nibName = type(of: self).description().components(separatedBy: ".").last!

let nib = UINib(nibName: nibName, bundle: bundle)

return nib.instantiate(withOwner: self, options: nil).first as! UIView

}

}

Inherit the NibView in your custom UIView class

The last step would be to create a custom UIView and a XIB file that will inherit from the NibView superclass.

class CustomView: NibView { }

Then, navigate to your XIB file, select File’s Owner from the left sidebar, and add your custom UIView as its custom class.

Now, go to your UIViewController, add a UIView component and add your UIView as a Custom Class. In order for this approach to work, remember to name your XIB file as your UIView class.

UIView initialized programmatically

This approach is used when you need to initialize your UIView directly from your UIViewController instead of its XIB file. I am using the same UIView extension that was mentioned above.

let customView = CustomView().loadNib() as! CustomView

customView.frame = /* add your frame */

view.addSubview(customView)

This is all you need to initialize your UIView together with your XIB file.