Swift 3 加载 xib。 NSBundle.mainBundle().loadNibNamed return 布尔
Swift 3 Load xib. NSBundle.mainBundle().loadNibNamed return Bool
我试图找出如何使用 xib 文件创建自定义视图。
在此question中使用了下一个方法。
NSBundle.mainBundle().loadNibNamed("CardView", owner: nil, options: nil)[0] as! UIView
Cocoa也有同样的方法,但是这个方法在swift3中变成了loadNibNamed(_:owner:topLevelObjects:),即returns Bool,前面的代码生成 "Type Bool has no subscript members" 错误,这是显而易见的,因为 return 类型是 Bool。
所以,我的问题是如何从 Swift 3
中的 xib 文件加载视图
首先Swift3.
中的方法没有改变
loadNibNamed(_:owner:topLevelObjects:)
已在 macOS 10.8 中引入,并出现在 Swift 的所有版本中。但是 loadNibNamed(nibName:owner:options:)
已在 Swift 3.
中删除
方法的签名是
func loadNibNamed(_ nibName: String,
owner: Any?,
topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray>?) -> Bool
所以你必须创建一个指针来获取 return 上的视图数组。
var topLevelObjects = NSArray()
if Bundle.main.loadNibNamed("CardView", owner: self, topLevelObjects: &topLevelObjects) {
let views = (topLevelObjects as Array).filter { [=11=] 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: { [=12=] is NSView }) as? NSView
}
Swift 4 @vadian 回答的版本
var topLevelObjects: NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName), owner: self, topLevelObjects: &topLevelObjects) {
return topLevelObjects?.first(where: { [=10=] is NSView } ) as? NSView
}
我写了一个安全的扩展,可以很容易地从 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: { [=10=] is T }) as? T
}
}
那么就这样使用:
let view: CustomView = .fromNib()
CustomView
是否是NSView
的子类并且CustomView.xib
.
我试图找出如何使用 xib 文件创建自定义视图。 在此question中使用了下一个方法。
NSBundle.mainBundle().loadNibNamed("CardView", owner: nil, options: nil)[0] as! UIView
Cocoa也有同样的方法,但是这个方法在swift3中变成了loadNibNamed(_:owner:topLevelObjects:),即returns Bool,前面的代码生成 "Type Bool has no subscript members" 错误,这是显而易见的,因为 return 类型是 Bool。
所以,我的问题是如何从 Swift 3
中的 xib 文件加载视图首先Swift3.
中的方法没有改变loadNibNamed(_:owner:topLevelObjects:)
已在 macOS 10.8 中引入,并出现在 Swift 的所有版本中。但是 loadNibNamed(nibName:owner:options:)
已在 Swift 3.
方法的签名是
func loadNibNamed(_ nibName: String,
owner: Any?,
topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray>?) -> Bool
所以你必须创建一个指针来获取 return 上的视图数组。
var topLevelObjects = NSArray()
if Bundle.main.loadNibNamed("CardView", owner: self, topLevelObjects: &topLevelObjects) {
let views = (topLevelObjects as Array).filter { [=11=] 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: { [=12=] is NSView }) as? NSView
}
Swift 4 @vadian 回答的版本
var topLevelObjects: NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName), owner: self, topLevelObjects: &topLevelObjects) {
return topLevelObjects?.first(where: { [=10=] is NSView } ) as? NSView
}
我写了一个安全的扩展,可以很容易地从 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: { [=10=] is T }) as? T
}
}
那么就这样使用:
let view: CustomView = .fromNib()
CustomView
是否是NSView
的子类并且CustomView.xib
.