NSArray содержит два элемента, но myArray [0] равен nil? - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь загрузить NIB из файла.

У меня есть этот код, с здесь

protocol NibLoadable {
  static var nibName: String? { get }
  static func createFromNib(in bundle: Bundle) -> Self?
}

extension NibLoadable where Self: NSView {

  static var nibName: String? {
    return String(describing: Self.self)
  }

  static func createFromNib(in bundle: Bundle = Bundle.main) -> Self? {
    guard let nibName = nibName else { return nil }
    var topLevelArray: NSArray? = nil
    bundle.loadNibNamed(NSNib.Name(nibName), owner: self, topLevelObjects: &topLevelArray)
    guard let results = topLevelArray else { return nil }
//    let views = Array<Any>(results).filter { $0 is Self }
//    return views.last as? Self
    let element =      results[0] as? Self

    return results[0] as? Self
  }
}

результаты имеют два элемента, NSView и NSApplication.

Проблема здесь в том, что element - ноль. Комментированный код также давал мне nil там.

Я новичок в Свифте. Что это за доставка Self или что она представляет в последней строке createFromNib?

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Не гарантируется, что первый объект является запрошенным представлением.

Получите правильный вид с помощью first(where

И объявить nibName необязательным как требование.

protocol NibLoadable {
    static var nibName: String { get }
    static func createFromNib(in bundle: Bundle) -> Self?
}

extension NibLoadable where Self: NSView {    
    static var nibName: String {
        return String(describing: Self.self)
    }

    static func createFromNib(in bundle: Bundle = Bundle.main) -> Self? {
        var topLevelArray: NSArray? // Optionals are nil by default
        bundle.loadNibNamed(NSNib.Name(nibName), owner: self, topLevelObjects: &topLevelArray)
        return topLevelArray?.first(where: { $0 is Self }) as? Self
    }
}
0 голосов
/ 26 июня 2019

После нескольких часов попыток возиться с несуществующей документацией, я пришел с этим, гораздо более простым.

  func loadViewFromNib() {

    var topLevelArray : NSArray?

    let bundle = Bundle(for: type(of: self))
    let nib = NSNib(nibNamed: .init(String(describing: type(of: self))), bundle: bundle)!
    nib.instantiate(withOwner: self, topLevelObjects: &topLevelArray)

    let myView = topLevelArray?.first(where: { $0 is NSView }) as? NSView
    addSubview(myView!)
}

Спасибо @vadian за все усилия.

...