LoginSignup
27
21

More than 5 years have passed since last update.

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

Posted at

はじめに

カスタム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さんありがとうございます。

27
21
3

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
27
21