Swift 3加载xib。 NSBundle.mainBundle()。loadNibNamed返回Bool

时间:2016-11-13 05:25:27

标签: cocoa swift3 xib nsview nib

我试图弄清楚如何使用xib文件创建自定义视图。 在此question中,使用了下一个方法。

NSBundle.mainBundle().loadNibNamed("CardView", owner: nil, options: nil)[0] as! UIView

Cocoa具有相同的方法,但是,此方法已在swift 3中更改为loadNibNamed(_:owner:topLevelObjects:)返回 Bool ,之前的代码生成 “类型Bool没有下标成员”错误,这很明显,因为返回类型是Bool。

所以,我的问题是如何从Swift 3中的xib文件加载视图

3 个答案:

答案 0 :(得分:9)

首先, Swift 3 中没有更改该方法。

loadNibNamed(_:owner:topLevelObjects:)已在macOS 10.8中引入,并且存在于所有版本的Swift中。但是在Swift 3中删除了loadNibNamed(nibName:owner:options:)

方法的签名是

func loadNibNamed(_ nibName: String, 
                      owner: Any?, 
            topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray>?) -> Bool

所以你必须创建一个指针来获取返回的视图数组。

var topLevelObjects = NSArray()
if Bundle.main.loadNibNamed("CardView", owner: self, topLevelObjects: &topLevelObjects) {
   let views = (topLevelObjects as Array).filter { $0 is NSView }
   return views[0] as! NSView
}

编辑:我更新了答案,以便可靠地过滤NSView实例。

Swift 4 中,语法略有变化,使用first(where效率更高:

var topLevelObjects : NSArray?
if Bundle.main.loadNibNamed(assistantNib, owner: self, topLevelObjects: &topLevelObjects) {
     return topLevelObjects!.first(where: { $0 is NSView }) as? NSView
}

答案 1 :(得分:5)

@ vadian的答案的Swift 4 版本

var topLevelObjects: NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName), owner: self, topLevelObjects: &topLevelObjects) {
    return topLevelObjects?.first(where: { $0 is NSView } ) as? NSView
}

答案 2 :(得分:2)

我编写了一个安全的扩展程序,可以很容易地从nib加载:

extension NSView {
    class func fromNib<T: NSView>() -> T? {
        var viewArray = NSArray()
        guard Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, topLevelObjects: &viewArray) else {
            return nil
        }
        return viewArray.first(where: { $0 is T }) as? T
    }
}

然后就这样使用:

let view: CustomView = .fromNib()

CustomViewNSView子类还是CustomView.xib