Customized UIView subclass from a xib file

[ad_1]

Loading xib recordsdata

Utilizing the contents of a xib file is a fairly rattling simple process to do. You need to use the next two strategies to load the contents (aka. the view hierarchy) of the file.


let view = UINib(nibName: "CustomView", bundle: .most important).instantiate(withOwner: nil, choices: nil).first as! UIView

view.body = self.view.bounds
self.view.addSubview(view)


The snippet above will merely instantiate a view object from the xib file. You’ll be able to have a number of root objects within the view hierarchy, however this time let’s simply decide the primary one and use that. I assume that in 99% of the circumstances that is what you will want to be able to get your customized views. Additionally you may lengthen the UIView object with any of the options above to create a generic view loader. Extra on that later… ๐Ÿ˜Š

This technique is fairly easy and low-cost, nonetheless there may be one little disadvantage. You’ll be able to’t get named pointers (shops) for the views, however just for the basis object. In case you are placing design components into your display screen, that is superb, but when that you must show dynamic knowledge, you would possibly wish to attain out for the underlying views as nicely. ๐Ÿ˜ƒ

Customized views with shops & actions

So the correct solution to load customized views from xib recordsdata goes one thing like this:

Inside your customized view object, you instantiate the xib file precisely the identical approach as I advised you proper up right here. ๐Ÿ‘† The one distinction is that you just need not use the item array returned by the strategies, however it’s a must to join your view objects via the interface builder, utilizing the File’s Proprietor as a reference level, plus a customized container view outlet, that’ll include the whole lot you want. ๐Ÿคจ



class CustomView: View {

    
    @IBOutlet weak var containerView: UIView!

    
    @IBOutlet weak var textLabel: UILabel!

    override func initialize() {
        tremendous.initialize()

        
        let identify = String(describing: sort(of: self))
        let nib = UINib(nibName: identify, bundle: .most important)
        nib.instantiate(withOwner: self, choices: nil)

        
        self.addSubview(self.containerView)
        self.containerView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            self.containerView.topAnchor.constraint(equalTo: self.topAnchor),
            self.containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
            self.containerView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            self.containerView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
        ])
    }
}


So the initialize technique right here is simply loading the nib file with the proprietor of self. After the loading course of completed, your outlet pointers are going to be crammed with correct values from the xib file. There’s one final thing that we have to do. Even the views from the xib file are “programmatically” linked to our customized view object, however visually they don’t seem to be. So we’ve got so as to add our container view into the view hierarchy. ๐Ÿค


If you wish to use your customized view object, you simply need to create a brand new occasion from it – inside a view controller – and eventually be happy so as to add it as a subview!

One phrase about bounds, frames aka. springs and struts: f*ckng UGLY! That is two phrases. They’re thought-about as a nasty observe, so please use auto structure, I’ve a pleasant tutorial about anchors, they’re superb and studying them takes about quarter-hour. ๐Ÿ˜…


class ViewController: UIViewController {

    weak var customView: CustomView!

    override func loadView() {
        tremendous.loadView()

        let customView = CustomView()
        self.view.addSubview(customView)
        NSLayoutConstraint.activate([
            customView.topAnchor.constraint(equalTo: self.view.topAnchor),
            customView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            customView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            customView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
        ])
        self.customView = customView
    }

    override func viewDidLoad() {
        tremendous.viewDidLoad()

        self.customView.textLabel.textual content = "Lorem ipsum"
    }
}


That is it, now you’ve a totally working customized UIView object that hundreds a xib file to be able to use it is contents. Wasn’t so unhealthy, proper? ๐Ÿคช

Yet another further factor. In the event you do not wish to deal with views programmatically otherwise you merely do not wish to fiddle with the loadView technique, simply take away it solely. Subsequent put the @IBOutlet key phrase proper earlier than your customized view class variable. Open your storyboard utilizing IB, then drag & drop a brand new UIView factor to your controller and join the customized view outlet. It ought to work like magic. ๐Ÿ’ซ


I promised shops and actions within the heading of this part, so let’s speak just a little bit about IBActions. They work precisely the identical as you’d count on them with controllers. You’ll be able to merely hook-up a button to your customized view and delegate the motion to the customized view class. If you wish to ahead touches or particular actions to a controller, you must use the delegate sample or go together with a easy block. ๐Ÿ˜Ž

Possession and container views

It’s doable to depart out all of the xib loading mechanism from the view occasion. We are able to create a set of extensions to be able to have a pleasant view loader with a customized view class from a xib file. This manner you do not want a container view anymore, additionally the proprietor of the file might be omitted from the sport, it is kind of the identical technique as reusable cells for tables and collections created by Apple. ๐ŸŽ

You need to know that going this manner you may’t use your default UIView init strategies programmatically anymore, as a result of the xib file will care for the init course of. Additionally if you’re attempting to make use of this sort of customized views from a storyboard or xib file, you will not have the ability to use your shops, as a result of the correspondig xib of the view class will not be loaded. In any other case if you’re attempting to load it manyally you will run into an infinite loop and finally your app will crash like hell. ๐Ÿ˜ˆ


import UIKit

extension UINib {
    func instantiate() -> Any? {
        return self.instantiate(withOwner: nil, choices: nil).first
    }
}

extension UIView {

    static var nib: UINib {
        return UINib(nibName: String(describing: self), bundle: nil)
    }

    static func instantiate(autolayout: Bool = true) -> Self {
        
        func instantiateUsingNib<T: UIView>(autolayout: Bool) -> T {
            let view = self.nib.instantiate() as! T
            view.translatesAutoresizingMaskIntoConstraints = !autolayout
            return view
        }
        return instantiateUsingNib(autolayout: autolayout)
    }
}

class CustomView: UIView {

    @IBOutlet weak var textLabel: UILabel!
}



Identical to with desk or assortment view cells this time it’s a must to set your customized view class on the view object, as an alternative of the File’s Proprietor. It’s important to join your shops and principally you are carried out with the whole lot. ๐Ÿคž


To any extent further you must ALWAYS use the instantiate technique in your customized view object. The excellent news is that the operate is generic, returns the correct occasion sort and it is extremely reusable. Oh, btw. I already talked about the unhealthy information… ๐Ÿคช

There’s additionally yet another method by overriding awakeAfter, however I’d not depend on that resolution anymore. In a lot of the circumstances you may merely set the File’s Proprietor to your customized view, and go together with a container, that is a protected guess. You probably have particular wants you would possibly want the second strategy, however please watch out with that. ๐Ÿ˜‰

[ad_2]

Leave a Reply