2016-11-13 39 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