LoginSignup
2
3

More than 5 years have passed since last update.

[macOS]NSNibからNSViewを簡単に生成するExtension

Last updated at Posted at 2017-09-18

先日、iOSDC2017があり非常に楽しかったということを伝えたいのと、自分も何かアウトプットしなければと思ったためにニッチですが1つ最近調べたことを紹介したいと思います。

NSNib

NSNibを使って.xibファイルからViewを生成しようとしたとき、UINibの感覚で使おうと思ってたらinstantiateの使い型が異なっていて困ってしまいました。

func instantiate(withOwner owner: Any?, topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray?>?) -> Bool

AutoreleasingUnsafeMutablePointerってなんだろう?🤔

最初よくわからなくてAutoreleasingUnsafeMutablePointer.initから頑張って作ったりしてたのですが、ここに載ってたコードによると話は単純で、Cライクにポインタを渡すように書けばいいだけみたいでした

instantiateの使い方
var topLevelObjects: NSArray = []
guard nib.instantiate(withOwner: owner, topLevelObjects: &topLevelObjects) else {
    ...
}
...

これを踏まえて、AppStoryboardの実装を参考にしてNSNib用にextensionを作成しました

コード

NSNib+instantiate.swift

import Foundation
import Cocoa

enum AppNib: String {
    case MyNibName1
    case MyNibName2

    var instance: NSNib {
        return NSNib(nibNamed: self.rawValue, bundle: Bundle.main)!
    }

    func view<T: NSView>(viewClass: T.Type) -> T {
        for object in instance.instantiate(withOwner: nil) {
            if let view = object as? T {
                return view
            }
        }

        fatalError("\(T.className()) is not found in \(self.rawValue) Nib.")
    }
}

extension NSView {
    static func instantiate(fromNib appNib: AppNib) -> Self {
        return appNib.view(viewClass: self)
    }
}

extension NSNib {
    public func instantiate(withOwner owner: Any?) -> [Any] {
        var topLevelObjects: NSArray = []
        guard instantiate(withOwner: owner, topLevelObjects: &topLevelObjects) else {
            return []
        }
        return topLevelObjects as? [Any] ?? []
    }
}

利用方法

let myview = MyView.instantiate(fromNib: .MyNibName1)

.xibのファイル名をあらかじめenumのAppNibに定義しておく必要があります

おわりに

iOSDC2017楽しかったです!

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3