我试图弄清楚如何使用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文件加载视图
答案 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()
CustomView
是NSView
子类还是CustomView.xib
。