Justin Leonard
Justin Leonard

Reputation: 81

loadnibnamed not loading subviews

I am trying to load a xib filed called "AddProgramView" using loadnibnamed when a user presses a button. I created the xib in storyboard, placed various subviews within the xib view, and hooked up outlets to a corresponding swift file named AddProgramView. When I load the xib, none of the subviews appear. They are all missing. Help? Here's my code

Within my main view controller:

@IBAction func addProgram(sender: UIButton) {

    if let _ = addProgramView {
        addProgramView!.frame = CGRectMake(0, self.window!.frame.origin.y + self.window!.frame.height, self.window!.frame.width, CGFloat(325))
    }
    else {
        let addProgramViews = NSBundle.mainBundle().loadNibNamed("AddProgramView", owner: self, options: nil)
        addProgramView = addProgramViews.first as? AddProgramView

        addProgramView!.frame = CGRectMake(0, self.window!.frame.origin.y + self.window!.frame.height, self.window!.frame.width, CGFloat(325))

        window?.addSubview(addProgramView!)
    }

    window?.bringSubviewToFront(addProgramView!)

    UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
        self.addProgramView!.frame.origin.y -= CGFloat(325)
        }, completion: nil)
}

The AddProgramView.swift file:

class AddProgramView: UIView {


    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var cancelButton: UIButton!

    @IBOutlet weak var instructionsLabel: UILabel!
}

Upvotes: 1

Views: 2536

Answers (2)

northernman
northernman

Reputation: 1446

Double-check that you don't have a size class specified in your xib file. It should say Any/Any at the bottom of the editor window.

Upvotes: 1

Aleš Kocur
Aleš Kocur

Reputation: 1898

First check, if you have your class name declared in the view itself, not in the file owner.

class name

If not, do it. Then try it again.

Another option is to create IBOutlet in your AddProgramView.swift

@IBOutlet var contentView: UIView!

and remove the class name from the view and add it to File's Owner.

owner's class name

Connect contentView by right-clicking at the File's owner:

enter image description here

Then create init methods like this:

class AddProgramView: UIView {
    @IBOutlet var contentView: UIView!

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

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

    func commonInit() {
        NSBundle.mainBundle().loadNibNamed("AddProgramView", owner: self, options: nil)
        self.addSubview(self.contentView)
        self.contentView.frame = self.bounds
    }
}

And now you can use the AddProgramView wherever you want. Either by init(frame:)

let addProgramView = AddProgramView.init(frame: CGRectMake(0, 0, 320, 30))

or you can use them directly inside storyboard by adding UIView and set them class to AddProgramView (No extra line of code, storyboard will call init(coder:) for you)

storyboard

I've created example project for you - CustomView project

Upvotes: 6

Related Questions