Posted at

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

More than 1 year has passed since last update.


はじめに

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