无法呈现ClassName的实例:代理程序在捆绑包中加载nib时抛出异常。

20

当我在storyboard或另一个nib中包含我的自定义IBDesignable视图时,代理程序会崩溃并抛出异常,因为它无法加载nib。

错误:IB Designables:无法更新自动布局状态:代理程序引发了“NSInternalInconsistencyException”异常:无法在bundle中加载名为'StripyView'的NIB:

这是我用来加载nib的代码:

override init(frame: CGRect) {
    super.init(frame: frame)
    loadContentViewFromNib()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    loadContentViewFromNib()
}

func loadContentViewFromNib() {
    let nib = UINib(nibName: String(StripyView), bundle: nil)
    let views = nib.instantiateWithOwner(self, options: nil)
    if let view = views.last as? UIView {
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
        addSubview(view)
    }
}

当我在模拟器中运行时,视图从nib文件正确加载,为什么它不会显示在Interface Builder中?

2个回答

44
当Interface Builder渲染你的IBDesignable视图时,它使用一个辅助应用程序加载所有内容。这意味着设计时间的mainBundle与辅助应用程序相关,而不是你的应用程序mainBundle。你可以看到错误信息中提到的路径与你的应用程序无关:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays

当加载nib文件时,你依赖于传递bundle:nil时默认使用你的应用程序的mainBundle来运行。
let nib = UINib(nibName: String(describing: StripyView.self), bundle: nil)

所以你需要在这里传递正确的 bundle。 请使用以下内容修复上述行:

let bundle = Bundle(for: StripyView.self)
let nib = UINib(nibName: String(describing: StripyView.self), bundle: bundle)

这将使Interface Builder从与您的自定义视图类相同的包中加载您的nib。

这适用于您的自定义视图从包中加载的任何内容,例如本地化字符串、图像等。如果您在视图中使用它们,请确保使用相同的方法并显式传递自定义视图类的包。


4
谢谢!这在许多教程中都缺失了。 - GoldenJoe
2
如果可以的话,我会给你100多分。我浪费了很多时间在这上面。 - Laura Calinoiu
很高兴能帮助你,Laura和Joe! - Josh Heald
我遇到了类似的问题。如果这个解决方案不起作用,请尝试我的答案(删除任何孤立的 IBOutlets)。https://dev59.com/BVYN5IYBdhLWcg3w5ryY#48388116 - Jacob F. Davis C-CISO

4
与“Josh Heald”持有相同的观点,我们不能将空值传递给bundle。对于使用Objective-C的用户来说,应该注意以下内容:
- (UIView *) loadViewFromNib{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:bundle];
UIView *v = [[nib instantiateWithOwner:self options:nil]objectAtIndex:0];
return v;
}

这个已经有大约1年的历史了,对我来说并不是完整的解决方案,但它帮我克服了一个主要障碍,即让nib文件成功加载。非常感谢! - Armand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接