【iOS】【swift】カスタムViewとxibを紐付ける

swiftで独自のViewを定義した時に、見た目をxibで整える方法をまとめます。

1. 独自のViewクラスの定義

class CustomView: UIView {
}

2. 空のxibファイルを作成

f:id:w6500:20151013090133p:plain

3. xibで見た目を作成

f:id:w6500:20151013090421p:plain

4. File's Ownerで先ほどの独自Viewクラスを指定

f:id:w6500:20151013090707p:plain

これで、とりあえずxibファイルとViewクラスが紐付いたので、各要素のOutletやActionを定義できるようになります。

5. Viewクラス側でxibファイルを読み込み、xibファイルで定義した一番親のViewを追加する

File's Ownerでクラスを指定しただけでは、xibファイルを読み込むことはしません。(してくれればいいのに)

Viewクラス側で明示的に読み込んであげる必要があります。
xibファイルを読み込むにはloadNibNamedを呼び出します。

// xibファイル名を指定
NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil)

loadNibNamedを呼び出したとしても、まだカスタムViewには要素は何も入っていない状態です。(入ってくれればいいのに)

xibファイルの親のViewをaddSubviewで明示的に追加してあげる必要があります。

カスタムViewクラスの全体をまとめるとこんな感じになります。

class CustomView: UIView {

    // xibファイルで定義した一番親のView
    @IBOutlet var contentView: UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)

        // xibファイル読み込み
        NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil)
       
        // Viewの大きさを定義
        bounds = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 44)
        contentView.frame = bounds

        // xibファイルのViewをカスタムViewクラスに追加する
        addSubview(contentView)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

これで、このカスタムViewの見た目をxibファイルで整えられるようになります。

紐付けた後に、わざわざaddSubviewで追加しないといけないというのが、ちょっとイメージしづらいなと思いました。