ios 从 xib 文件加载 ViewController

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37046573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:00:31  来源:igfitidea点击:

Loading ViewController from xib file

iosswiftinitializationxibviewcontroller

提问by bluenowhere

I had a MyViewController.swiftand a MyViewController.xibpresenting the layout of MyViewController.

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

I tried different 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 one is the only successful initialisation, but the previous two are causing error:

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

Terminating app due to uncaught exception 'NSUnknownKeyException',

reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key XXX.

由于未捕获的异常“NSUnknownKeyException”而终止应用程序,

原因: '[ setValue:forUndefinedKey:]: 此类不是密钥 XXX 的密钥值编码兼容。

What's wrong with those loading methods?

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

回答by Marcos Reboucas

Swift 3

斯威夫特 3

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

or push in navigation controller

或推入导航控制器

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

回答by AechoLiu

File's Owner

文件所有者

Notice the File's Owner. In your case, the File's Ownermust be MyViewController, or its sub-class.

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

And the following code, if it executes in class Foo.

下面的代码,如果它在 class 中执行Foo

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

It assigns selfas owner. So, the File's Owneris Foo, not MyViewController. Then, for Fooclass, those IBOutletcannot be connected to Foo. So, it throws exception.

它分配selfowner. 所以,File's OwnerFoo,不是MyViewController。然后,对于Foo类,那些IBOutlet不能连接到Foo. 所以,它抛出异常。

回答by SamehDos

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()

回答by Sanman

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

问题不在于方法……您可能已经为某些 uielement 连接了一个插座(XXX)并将其从相应的控制器中删除……我正在下面添加示例……enter image description here

the above button is connected to controller now but when i comment outlet enter image description here

上面的按钮现在连接到控制器但是当我评论出口时 enter image description here

my app crashes enter image description here

我的应用程序崩溃 enter image description here

enter image description here

enter image description here

so try to find outlet(xxx) that is missing from viewcontroller but is in xib file.Hope it helps :)

所以尝试找到viewcontroller中缺少但在xib文件中的outlet(xxx)。希望它有帮助:)

回答by Archangel

I had the same problem. The automatically generated xib had a UIView in it. You have to delete the view, add new view controller to the xib, set the view controller class to the one you want and then connect the outlets. After all of this you can use the codes provided above to get an instance of this view controller, like this:

我有同样的问题。自动生成的 xib 中有一个 UIView。您必须删除视图,将新的视图控制器添加到 xib,将视图控制器类设置为您想要的类,然后连接插座。完成所有这些之后,您可以使用上面提供的代码来获取此视图控制器的实例,如下所示:

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

回答by Jigar Tarsariya

Try below code,

试试下面的代码,

//1

//1

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

//2

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

This will work.

这将起作用。

回答by rustyMagnet

@AechoLiu's answer is great. I had the same question and answered it with the below fix.

@AechoLiu 的回答很棒。我有同样的问题,并通过以下修复回答了它。

Problem:

问题:

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

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

Fix:

使固定:

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

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

I had accidentally cast my Nib file to the wrong Clas ( NSViewController ), despite having it connected correctly inside the .xib file.

我不小心将我的 Nib 文件转换为错误的 Clas ( NSViewController ),尽管它在 .xib 文件中正确连接。

回答by rswayz

Updated for Swift 5

为 Swift 5 更新

        let myVC = Bundle.main.loadNibNamed("MyViewController", owner: self, options: nil)![0] as? MyViewController

回答by Wimukthi Rajapaksha

I removed File owner's class name and set that to the class name of first view. And then I had to set outlets to the components which I'm going to use.

我删除了文件所有者的类名并将其设置为第一个视图的类名。然后我必须为我将要使用的组件设置出口。

Then I loaded that view class like

然后我加载了那个视图类

let myViewController = Bundle.main.loadNibNamed("MyViewController", owner: self, options: nil)?.first as! MyViewController
view.addSubview(myViewController)