如何使用顶级ViewController加载XIB?

我有一个带有视图控制器根元素的笔尖,如下所示:

在此处输入图像描述

所以我可以使用自动布局相对于顶部和底部布局指南定位元素。

当我第一次尝试使用时加载此笔尖

SearchViewControllerPro* searchViewController = [[SearchViewControllerPro alloc]initWithNibName:@"SearchViewControllerPro" bundle:[NSBundle mainBundle]]; 

我得到以下运行时exception:

因未捕获的exception’NSInternalInconsistencyException’而终止应用程序,原因:’ – [UIViewController _loadViewFromNibNamed:bundle:]加载了“SearchViewControllerPro”笔尖,但未设置视图sockets。

谷歌搜索我指出的错误,需要将xib的文件所有者设置为我的视图控制器的类,并且必须将视图插件设置为xib中的视图对象。 如果我这样做,那么我得到以下运行时错误:

由于未捕获的exception’UIViewControllerHierarchyInconsistency’而终止应用程序,原因:’一个视图一次最多只能与一个视图控制器相关联! 视图>与…相关联。 在将此视图与。关联之前清除此关联。

由于视图与文件所有者和nib的顶级视图控制器相关联,因此不会令人感到意外。 但是,我怎么能告诉运行时它们实际上是同一个东西而不是两个独立的实体呢?

编辑:当我尝试从nib中取消ViewController时,如此

 NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:nil options:nil]; SearchViewControllerPro* mapSearchViewController = [xibContents lastObject]; 

,它也没有好处:

由于未捕获的exception’NSUnknownKeyException’而终止应用程序,原因:'[setValue:forUndefinedKey:]:此类不是键视图的键值编码兼容。

临时解决方案:

我找到了一个解决方案,但它并不漂亮。 尽管IB中显示了结构,但视图控制器不是xib中的最后一个对象。 所以我有:

 __block SearchViewControllerPro* mapSearchViewController = nil; [xibContents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[SearchViewControllerPro class]]) { mapSearchViewController = obj; } }]; 

这似乎没有运行时崩溃。 但是,它只是干净的代码。

我怎么能告诉运行时它们实际上是同一个东西而不是两个独立的实体?

你不能,因为他们不是一回事。 您已经创建了两个SearchViewControllerPro实体。

您需要alloc-init一个SearchViewControllerPro实例或从一个nib中取消归档一个。

如果您决定在nib中创建ViewController,则访问它的常用方法与访问您在nib中创建的任何其他项(视图,按钮,文本字段)的方式相同。

向FilesOwner对象添加一个出口,在接口构建器中连接该连接,并确保在取消归档该nib时传递该对象。

例如,如果您希望取消归档nib的Object为FilesOwner:

 [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:self options:nil]; 

以下工作以及(至少对我来说)更明确的是为ViewController创建一个sockets:

 NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:nil options:nil]; SearchViewControllerPro* mapSearchViewController = [xibContents objectAtIndex:0]; 
 if (isIPad) { [[NSBundle mainBundle] loadNibNamed:@"ABC_iPad" owner:self options:nil]; } else{ [[NSBundle mainBundle] loadNibNamed:@"ABC_iPhone" owner:self options:nil]; }