Search code examples
iosswiftxcodeuiviewinterface-builder

Custom view created with Xib not working in Interface Builder


I've created a custom view with the help of an .Xib file. When I create the view programmatically and add it to my ViewController it works just fine. But if I create a UIView in Interface Builder and set the class to my CustomView class and run it, it doesn't show up.

This is the Code in my CustomView class:

@IBOutlet var view: UIView!

init() {
    super.init(frame:CGRect.zero)
    setup()
}

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

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


func setup() {
    Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)
    view.backgroundColor = UIColor(red: 10.0/255.0, green: 30.0/255.0, blue: 52.0/255.0, alpha: 1.0)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.isUserInteractionEnabled = true
}


func presentInView(superView:UIView) {

    superView.addSubview(view)

    // Define Constraints
    let height = NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 90.0)
    view.addConstraint(height)

    let topConstraint = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: superView, attribute: .top, multiplier: 1.0, constant: 0.0)
    let leftConstraint = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: superView, attribute: .left, multiplier: 1.0, constant: 0.0)
    let rightConstraint = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: superView, attribute: .right, multiplier: 1.0, constant: 0.0)
    superView.addConstraints([topConstraint,leftConstraint, rightConstraint])
}

In the .Xib file I set the class for the Files Owner to CustomView and the connect the IBOutlet view to the main view in the .Xib.

In my ViewController I did this to add the CustomView to it:

let customView = CustomView()
customView.presentInView(superView: self.view)

When I add a UIView in Interface Builder it should work just as it does when I do it programmatically.


Solution

  • The Problem was the size of the view, the IBOutlet that I connected to my view in the .Xib file. When I created my CustomView in code, I also called the presentInView method, which I thought was unnecessary when created in the Interface Builder because I set the constraints there. But I forgot, that the constraints that I set in Interface Builder are for the class itself and not for its view outlet. So the view needs constraints to hold it in its superview, which is not the ViewController.view but CustomView. Thats why I also have to write self.addSubview(view)

    With these changes it works. Here is the final code:

    func setup() {
    
        Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)
        view.backgroundColor = UIColor(red: 10.0/255.0, green: 30.0/255.0, blue: 52.0/255.0, alpha: 1.0)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isUserInteractionEnabled = true
        self.addSubview(view)
    
        let topConstraint = NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0)
        let leftConstraint = NSLayoutConstraint(item: view, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1.0, constant: 0.0)
        let rightConstraint = NSLayoutConstraint(item: view, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1.0, constant: 0.0)
        let bottomConstraint = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0)
        self.addConstraints([topConstraint,leftConstraint, rightConstraint, bottomConstraint])
    
    }
    

    The presentInView method is no longer needed.

    Hope it helps if someone else has a problem like this.