カスタムViewをNibから初期化の最新版

  • 9
    Like
  • 3
    Comment

はじめに

カスタムViewをNibから初期化し、IBDesignableとIBInspectableで便利に使う
こちらの記事を参考にしてXibをコードから生成したり、View部品を作っています。
対象の記事が古くなっていたので、コードの部分のみを書き直します。

親クラスを作成する。

元の記事ではそのまま書かれていましたが、僕はいくつもの部品を作りたかったので親クラスを作成しました。

class UINibView: UIView {
    // コードから初期化はここから
    override init(frame: CGRect) {
        super.init(frame: frame)
        comminInit()
    }

    // Storyboard/xib から初期化はここから
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        comminInit()
    }

    // 初期化後に呼びされる。
    func afterInit() {}

    // xibからカスタムViewを読み込んで準備する
    private func comminInit() {
        // MyCustomView.xib からカスタムViewをロードする
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: self.className, bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
        addSubview(view)

        // カスタムViewのサイズを自分自身と同じサイズにする
        view.translatesAutoresizingMaskIntoConstraints = false
        let bindings = ["view": view]
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|",
                                                      options:NSLayoutFormatOptions(rawValue: 0),
                                                      metrics:nil,
                                                      views: bindings))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|",
                                                      options:NSLayoutFormatOptions(rawValue: 0),
                                                      metrics:nil,
                                                      views: bindings))

        self.afterInit()
    }

    // このメソッドはextensionにすると使い勝手が良いです。
    var className: String {
        get {
            return type(of: self).className
        }
    }
}

後は元記事の以下のコードを変更します。

class MyCustomView: UIView {
...
}

class MyCustomView: UINibView {
// ここのコードは不要です。

    // 以下のコードはサンプルですが、後は普通に接続できます。
    @IBOutlet weak private var nameLabel:UILabel!

    // 初期化後
    override func afterInit() {
        nameLabel.text = "テスト"
    }
}

最後に

NibのViewについているRefelencing Outletsは不要なので消しちゃってください。
つけたままにしていると落ちると思います。

@himara2さんありがとうございます。