Swift 3 загрузить xib. NSBundle.mainBundle().loadNibNamed вернуть Боол

Я пытался выяснить, как создать пользовательское представление с помощью xib-файлов. В этом вопрос использовать следующий метод.

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

Cocoa имеет тот же метод,однако этот метод изменился в swift 3 на loadNibNamed (_: owner:topLevelObjects:), который возвращает Bool, и предыдущий код создает "тип Bool не имеет членов индекса" error, что очевидно, так как возвращаемый тип Тип bool.

Итак, мой вопрос в том, как загрузить представление из xib-файла в Swift 3

3 ответов


прежде всего метод не был изменен в Swift 3.

loadNibNamed(_:owner:topLevelObjects:) был представлен в macOS 10.8 и присутствовал во всех версиях Swift. Однако loadNibNamed(nibName:owner:options:) был сброшен в Swift 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 {  is NSView }
   return views[0] as! NSView
}

Edit: я обновил ответ, чтобы отфильтровать NSView экземпляр надежно.


на Swift 4 синтаксис слегка изменен и используется first(where более эффективен:

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

Swift 4 версия ответы @вадиан это

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

я написал расширение, которое безопасно и позволяет легко загружать с наконечника:

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: {  is T }) as? T
    }
}

тогда просто используйте так:

let view: CustomView = .fromNib()

ли CustomView это NSView подкласс, а также CustomView.xib.