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