Xibのインスタンス化方法まとめ
Xcodeには、コードを書かずにユーザインタフェースを構築することのできるInterface Builderがあります。画面を視覚的にデザインでき、Auto Layoutも比較的付けやすいので、多くのプロジェクトでIBが採用されています。この記事では、IBとソースコードを紐付ける方法をまとめます。
それでは早速、IBとコードの構成について、ViewControllerとCustom Viewの2つに分けて説明します。
ViewController
1 Storyboard — N ViewController
一番簡単な作り方です。Segueによる画面遷移ができ、それらの関連がわかりやすいことがメリットとして挙げられます。
【実装方法】
この構成の作り方はとても簡単です。まず、 New File...
から新しいVCのクラスを作ります。次に、利用するStoryboard (おそらく Main.storyboard
) に新しいVCを置き、 Class
に先ほど作ったクラスを設定します。 Storyboard ID
に適当な文字列を指定すれば完了です。
【インスタンス化】
1つのStoryboardに複数のVCを配置している場合には、先ほど設定した Storyboard ID
を使ってインスタンス化します。
1 Storyboard — 1 ViewController
1つのVCにつき1つのStoryBoardを用意する作り方です。共同開発におけるコンフリクトが少なくなリます。
【実装方法】New File...
から新しいStoryboardを作ります。名前はクラスと同じにすると良いでしょう。そこにVCを設置し、プロパティの中の Is Initial View Controller
にチェックを入れましょう。VCの左側に矢印がつきます。あとは1 Storyboard — N ViewControllerの時と同様です。
【インスタンス化】
こちらも1 Storyboard — N ViewControllerの時と似ていますが、今回は同一Storyboard上にVCがないことに注意してください。以下のコードでインスタンス化できます。
UIStoryboardのイニシャライザの引数について、 name
には.storyboardファイルの拡張子を除いた部分の文字列を、 bundle
には指定した.storyboardファイルとそれに関連するリソースが含まれているbundleを渡してあげます。上のコードのようにbundleにnilを渡すと、このメソッドはmain bundleを見に行きます。 Bundle.main
としてあげても良いでしょう。
1 xib — 1 ViewController
1つのVCにつき1つのxibファイルを用意してあげる構成です。
【実装方法】
クラス作成時のダイアログにて Also create XIB file
にチェックを入れてあげれば、.swiftファイルとそれに関連づけられた.xibファイルが生成されます。
すでに作成済みの.swiftファイルに.xibファイルを関連づけたい場合には、 File's Owner
にVCのクラスを指定し、RootのviewをFile’s Ownerに関連付けしてあげれば完了です。
【インスタンス化】
作成したVCのイニシャライザを使ってインスタンス化を行います。 nibName
には.xibファイルの拡張子を除いた部分の名前を渡します。
Custom View
1 xib — 1 View
カスタムviewから遷移をすることはないので、xibを使うのが無難です。関連のあるviewたちを1つのStoryboardでまとめて管理するやり方もありますが、衛生的にあまりよくありません。特にメリットがないので、.xibファイルで作ることをお勧めします。
【実装方法】
.xibファイルのFile’s Ownerに対し、作成したカスタムクラスを指定します。先ほどと違い、Root viewへの関連付けは必要ありません。
【インスタンス化】
UIViewのイニシャライザをoverrideし、それぞれでxibをインスタンス化して addSubview
します。
IBとコードの構成については以上です。ここから先はtipsです。
ファイル名のお作法
たいそれた内容ではありませんが、.storyboardもしくは.xibファイルの名前は、カスタムクラス (≒対応した.swiftファイル)と同じにしておくのが定石です。命名規則を統一するというのももちろんですが、クラス名にすることで以下のように、protocolなどを用いてインスタンス化のコードを共通化しやすくなります。
修正 — 2019/05/31
この命名規則を守と、上記のメリットだけでなく、インスタンス化時にnibNameを指定する必要が無くなります。詳細は次のセクションに書きます。
Storyboardとxibの違い
IBで作ることのできるファイルには、Storyboardとxibの2種類がありますが、その違いはさほどありません。Storyboardはxibの上位互換であり、画面の遷移を管理することができます。機能的な違いはそれだけです。同じデザインの画面を作った場合にも、.xibファイルよりも.storyboardファイルの方が容量が大きくなるといったこともありません。共同開発のしやすさや、この記事にまとめている実装とインスタンス化の方法を比べて、好きな方を採用すれば良いと思います。
修正 — 2019/05/31
違いはさほどないと述べましたが、修正します。下記の理由より、xibの利用をお勧めします。
まず、viewやviewControllerを直接初期化することができます。Storyboardで作成した場合には UIStoryboard
からインスタンス化しますが、xibで作成した場合には、カスタムクラスのイニシャライザを用いてインスタンス化をします。これで何が嬉しいかというと、イニシャライズするときに初期値を与えることができます。こうすることで、 let
で宣言できるようになります。
次に、カスタムクラス内で loadView()
をoverrideしていない場合、以下の2つどちらかの命名規則に従っていればnibNameを指定しなくてもインスタンス化することができます。
- xibファイルの名前ががカスタムクラスと同じ
(e.g. SecondViewController.swift <-> SecondViewController.xib) - カスタムクラス名が“Controller”で終わる場合、xibファイルの名前がカスタムクラス名から“Controller”を除いた値と同じ
(e.g. SecondViewController.swift <-> SecondView.xib)
これにより以下のコードでインスタンス化することができます。
File’s OwnerかCustom classか
この記事でのCustom View生成方法では、インスタンス化コードからもわかる通り、 CustomView
クラスを継承したRoot viewの上に通常のUIViewを一枚挟んでから、IB上で配置した部品が載ります。これは、UIView一枚分のメモリが無駄に感じるかもしれません。
File’s Ownerではなく、Root viewに直接Custom classとして指定すれば無駄なUIViewを挟む必要はありません。しかしながらコードで init(frame:)
を呼ばれてしまうと、その時点で CustomView
がインスタンス化されてしまうため、xibと結びつけることができません。コードから呼び出す場合には別途 static
関数などを用意し、そちらを利用する必要があります。
一方、File’s Ownerに指定する方法であれば、コード上でもIB上でもUIViewと変わらず自然に扱うことができます。UIView一枚分であればパフォーマンスもさほど変わらないことが予想されるので、 File’s Ownerを用いる方法をお勧めします。
本記事では、Interface Builderで作成した画面をソースコードに紐付ける方法をまとめました。実装方法やインスタンス化のコードを踏まえ、自分のプロジェクトにあったものを採用するのが良いでしょう。