2016-11-13 79 views
6

我想弄清楚如何使用xib文件创建自定义视图。 在这个question中使用了下一个方法。Swift 3加载xib。 NSBundle.mainBundle()。loadNibNamed return Bool

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

可可具有相同的方法,但是,这种方法已在迅速改变3至loadNibNamed(_:owner:topLevelObjects:),其返回布尔,和前面的代码生成“BOOL类型没有下标成员”错误,这很明显,因为返回类型是Bool。

所以,我的问题是如何从厦门国际银行文件中的斯威夫特3负载视图

回答

8

首先该方法尚未在改变斯威夫特3

loadNibNamed(_:owner:topLevelObjects:)已经在macOS 10.8中引入,并出现在所有版本的Swift中。然而loadNibNamed(nibName:owner:options:)已斯威夫特3.被丢弃

方法的签名是

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实例。


斯威夫特4语法略有改变,并使用first(where更高效:

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

在一行上让view = topLevelObjects [0] as! NSView - 我收到错误“无法将'NSApplication'类型的值(0x7fffd8201278)转换为'NSView'(0x7fffd8210048)。” – Alex

+0

调用此方法假定有一个包含视图的nib/xib文件作为顶级对象。 – vadian

+0

谢谢,发现一个错误。 – Alex

2

斯威夫特4版本@ vadian的回答

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

我写了一个扩展这是安全的,可以很容易地从笔尖加载:

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