7

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

在此处输入图像描述

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

当我第一次尝试使用

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

我得到以下运行时异常:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[UIViewController _loadViewFromNibNamed:bundle:] 加载了“SearchViewControllerPro”笔尖,但未设置视图出口。

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

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

这并不奇怪,因为视图与文件所有者和 nib 的顶级视图控制器相关联。但是我怎么能告诉运行时它们实际上是同一个东西而不是两个独立的实体呢?

编辑: 当我尝试像这样从笔尖解开 ViewController 时,

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

,它也没有好处:

由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[setValue:forUndefinedKey:]:此类与键视图的键值编码不兼容。

临时解决方案:

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

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

这似乎在没有运行时崩溃的情况下工作。但是,除了干净的代码之外,一切都是如此。

4

3 回答 3

4

我如何告诉运行时它们实际上是同一事物而不是两个独立的实体?

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

您需要分配初始化 SearchViewControllerPro 实例或从 nib 取消归档一个实例。

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

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

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

[[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:self options:nil];
于 2013-09-25T11:00:28.327 回答
3

以下内容也有效,并且(至少对我而言)比为 ViewController 创建一个出口更加明确:

NSArray* xibContents = [[NSBundle mainBundle] loadNibNamed:@"SearchViewControllerPro" owner:nil options:nil];
SearchViewControllerPro* mapSearchViewController = [xibContents objectAtIndex:0];
于 2013-09-25T12:40:07.703 回答
0
if (isIPad)
{
    [[NSBundle mainBundle] loadNibNamed:@"ABC_iPad" owner:self
options:nil];

}
else{
    [[NSBundle mainBundle] loadNibNamed:@"ABC_iPhone" owner:self options:nil];

}
于 2016-10-24T09:16:53.713 回答