Download ViewController from xib file

I had MyViewController.swift and MyViewController.xib representing the layout of MyViewController.

I tried various methods to load this view controller, including:

 //1 let myVC = UINib(nibName: "MyViewController", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? MyViewController //2 let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController //3 let myVC = MyViewController(nibName: "MyViewController", bundle: nil) 

The third is the only successful initialization, but the previous two cause an error:

Application termination due to the uncaught exception "NSUnknownKeyException",

reason: '[setValue: forUndefinedKey:]: this class does not match the key value for key XXX.

What is wrong with these boot methods?

+26
source share
7 answers

Swift 3

 let myViewController = MyViewController(nibName: "MyViewController", bundle: nil) self.present(myViewController, animated: true, completion: nil) 

or click on the navigation controller

 self.navigationController!.pushViewController(MyViewController(nibName: "MyViewController", bundle: nil), animated: true) 
+65
source

File's owner

Pay attention to File Owner . In your case, the File Owner should be MyViewController or its sub-class .

And the following codes if it is executed in the Foo class.

 // If 'self' is an instance of 'Foo' class. // In this case, 'File Owner' will be a 'Foo' instance due to 'self' parameter. let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController 

He assigns self as owner . So File Owner is Foo , not MyViewController . Then, for the Foo class, these IBOutlet cannot be connected to Foo . So this is the exception.

+12
source
 extension UIViewController { static func loadFromNib() -> Self { func instantiateFromNib<T: UIViewController>() -> T { return T.init(nibName: String(describing: T.self), bundle: nil) } return instantiateFromNib() } } 

Use it as the following: -

 let testVC = TestVC.loadFromNib() 
+5
source

The problem is not with the methods ... you probably saved the output (XXX) connected for some uielement and removed it from the corresponding controller ... I am adding an example below ... enter image description here

the above button connects to the controller, but when I comment on the output enter image description here

My application crashes enter image description here

enter image description here

try to find the output (xxx) that is not in the viewcontroller but is in the xib file. Hope helps :)

+2
source

I had the same problem. Automatically generated xib had a UIView. You must remove the view, add a new view controller in xib, set the view controller class to the one you want, and then connect the outputs. After that, you can use the codes above to get an instance of this controller of the form, for example:

 if let menuVC = Bundle.main.loadNibNamed("MenuViewController", owner: nil, options: nil)?.first as? MenuViewController { menuVC.profileType = profileType vc.present(menuVC, animated: true, completion: nil) } 
+2
source

@AechoLiu the answer is excellent. I had the same question, and I answered it with the correction below.

Problem:

let vc1 = NSViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)

Fix:

let vc1 = MyPlainViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)

I accidentally brought my Nib file to the wrong Clas (NSViewController), despite the fact that it is correctly connected inside the .xib file.

0
source

Try entering the code,

//one

 let nib = UINib(nibName: "MyViewController", bundle:nil) myVC = nib.instantiateWithOwner(self, options: nil)[0] as? MyViewController 

OR

 myVC = nib.instantiateWithOwner(self, options: nil).first as? MyViewController 

// 2

 let nib : NSArray = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil) myVC = nib.objectAtIndex(0) as? MyViewController 

This will work.

-one
source

All Articles