ios - 如何使用顶级 ViewController 加载 XIB?

标签 ios uiview uiviewcontroller interface-builder xib

我有一个带有像这样的 View Controller 根元素的 Nib :

enter image description here

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

当我第一次尝试使用加载这个 Nib 时

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

我得到以下运行时异常:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SearchViewControllerPro" nib but the view outlet was not set.'

谷歌搜索向我指出的错误,需要将 xib 的文件所有者设置为我的 View Controller 的类,并且必须将 View 导出设置为 xib 中的 View 对象。如果这样做,则会出现以下运行时错误:

Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View > is associated with . Clear this association before associating this view with .'

这并不奇怪,因为 View 与文件所有者和 nib 的顶级 View Controller 相关联。但我如何才能告诉运行时它们实际上是同一事物而不是两个独立的实体?

编辑: 当我尝试像这样从 nib 中解压 ViewController 时,

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

,它也没有好处:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.

临时解决方案:

我找到了一个解决方案,但它并不完美。尽管 IB 中显示的结构, View Controller 不是 xib 中的最后一个对象。所以我有:

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

这似乎在没有运行时崩溃的情况下工作。然而,除了干净的代码,它什么都不是。

最佳答案

how can I tell the run-time that they are both in fact the very same thing instead of two separate entities?

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

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

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

向 FilesOwner 对象添加一个导出,在界面构建器中连接连接,并确保在取消存档 Nib 时传递该对象。

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

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

关于ios - 如何使用顶级 ViewController 加载 XIB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19001808/

相关文章:

ios - 在 Swift 中将字典复制到数组中

ios - 使用贝塞尔曲线路径剪辑 UIView。 BezierPath似乎没有完全应用

iphone - presentModalViewController 什么都不做

ios - 更改 Root View Controller 将 IBOutlet 设为 nil

iphone - 旋转 UIView - willRotateToInterfaceOrientation 未被调用

iOS - UIPageControl 上的 UIButton 不工作

ios - 应用程序在 iOS 模拟器中打开后很快就会关闭

ios - Facebook SDK ios v4.4.0 didFinishLaunchingWithOptions

ios - 如何在 Swift 4 中访问相机?

iphone - self.frame 与 self.layer.bounds(在 iOS 中)