从xib文件加载ViewController

blu*_*ere 28 initialization xib viewcontroller ios swift

我有一个MyViewController.swift和一个MyViewController.xib呈现MyViewController的布局.

我尝试了不同的方法加载这个视图控制器,包括:

//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)
Run Code Online (Sandbox Code Playgroud)

第三个是唯一成功的初始化,但前两个导致错误:

由于未捕获的异常'NSUnknownKeyException'而终止应用,

reason:'[setValue:forUndefinedKey:]:此类不是密钥XXX的密钥值编码兼容.

这些加载方法有什么问题?

Mar*_*cas 72

斯威夫特3

let myViewController = MyViewController(nibName: "MyViewController", bundle: nil)
self.present(myViewController, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

或推入导航控制器

self.navigationController!.pushViewController(MyViewController(nibName: "MyViewController", bundle: nil), animated: true)
Run Code Online (Sandbox Code Playgroud)

  • 我收到错误“已加载“...”笔尖,但未设置视图出口。” (3认同)
  • @Woodstock:有点!这是“如何从XIB文件中加载ViewController的布局”这一问题的正确答案。但是,原始问题是模棱两可的,因为OP似乎无法区分(1)从XIB加载以编程方式实例化的ViewController的布局(View),和(2)从XIB加载ViewController实例* self *。刘德e的答案是第二种解释的正确答案:-) (2认同)
  • 如果您的vc名称与xib文件相同,则可以使用(nibName:nil,bundle:nil)并且它将起作用 (2认同)

Aec*_*Liu 12

文件的所有者

请注意File's Owner.在你的情况下,File's Owner必须是MyViewController,或者是sub-class.

以下代码,如果它在课堂上执行Foo.

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

它通过selfowner.所以,File's OwnerFoo,不是MyViewController.然后,对于Foo课堂,那些IBOutlet不能连接Foo,那些File's Owner是为了File's Owner.所以,它崩溃了.


Sam*_*Dos 9

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

        return instantiateFromNib()
    }
}
Run Code Online (Sandbox Code Playgroud)

使用它如下:

let testVC = TestVC.loadFromNib()
Run Code Online (Sandbox Code Playgroud)

  • 这是避免一堆重复代码的好方法!您应该注意,nib 文件的名称需要与类的名称相同。 (2认同)

Jig*_*iya 1

尝试下面的代码,

//1

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

或者

myVC = nib.instantiateWithOwner(self, options: nil).first as? MyViewController
Run Code Online (Sandbox Code Playgroud)

//2

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

这会起作用。

  • 请不要只用代码来解释错误所在以及您的代码如何帮助解决它:) (3认同)