Search code examples
iosswiftuiviewconstraintsnib

Loading a custom view with a nib causes constraints being removed


Overview
I created a custom view class and an associated nib. When I try to load it in another view controller, it loads it but the constraints are removed.

What I found
Before marking this as a duplicate... I read plenty of questions on StackOverflow of people having the same issues but the ones in swift were either unanswered either non-working. I tried everything.

What I'm doing
I have a view controller (which happens to be a keyboardviewcntroller but on a regular one I still have the problem) with an associated nib and a custom uiView with its associated nib.

  • KeyboardViewController:
    I associated with my Keyboard view controller a zip file. His file owner is KeyboardViewController.
    In my KeyboardViewController I have the basic code you get by creating a keyboard target and then I added the custom view outlet before the viewDidLoad
    @IBOutlet weak var vieww: Custom!
    and inside of my viewDidLoad I loaded my nib
let nib = UINib(nibName: "nibbb", bundle: nil)
let objects = nib.instantiate(withOwner: self, options: nil)
view = objects[0] as? UIView
  • Custom view
    My custom view has an associated nib too. Its file owner is Custom (my new class). In the nib I put a button and a label as shown in the picture below and I added some constraints.
    In the Custom class, I put the following code which includes outlets and the init of the class.
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var button: UIButton!
    
    override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            commonInit()
           
        }
        
        private func commonInit(){
            Bundle.main.loadNibNamed("Custom", owner: self, options: nil)
            
            addSubview(label)
            label.frame = self.bounds
           
            label.autoresizingMask = [.flexibleHeight, .flexibleWidth]
            addSubview(button)
            button.frame = self.bounds
           
            button.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        }

}

enter image description here

This is the output i get:
enter image description here

and of course, it's not what I wanted.

Question
How do I load a custom UIView nib from another view controller without having my constraints being messed up?


Solution

  • The reason your constraints are not working as expected is because in the commonInit function sets both the label and button to be the same size as the view is.

    You should declare a UIView property and then replace the content of commonInit function:

    var contentView: UIView!
    
    private func commonInit() {
        if let nib = Bundle.main.loadNibNamed("Custom", owner: self, options:nil)?.first as? UIView {
            contentView = nib
            contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            contentView.frame = bounds
            addSubview(contentView)
        }
    }