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
Loading ViewController from xib file
提问by bluenowhere
I had a MyViewController.swift
and a MyViewController.xib
presenting 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
Notice the File's Owner
. In your case, the File's Owner
must 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 self
as owner
. So, the File's Owner
is Foo
, not MyViewController
. Then, for Foo
class, those IBOutlet
cannot be connected to Foo
. So, it throws exception.
它分配self
为owner
. 所以,File's Owner
是Foo
,不是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...
问题不在于方法……您可能已经为某些 uielement 连接了一个插座(XXX)并将其从相应的控制器中删除……我正在下面添加示例……
the above button is connected to controller now but when i comment outlet
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)