はじめに
いきなりですが、XcodeのVary for Traits という機能をご存知ですか?
InterfaceBuilderの下のバーにある、グレーのボタンで使うことができます。
一体どういうことができる機能かというと、コードの記述なしに端末の画面サイズや回転状況に応じて、AutoLayoutの制約を付け替えたり、制約の数値を変更、色の変更などのレイアウト周りの設定の変更を行うことができます。
それによってiPhoneとiPad間でのレイアウト崩れを防いだり、画面回転時に全く違うレイアウトを表示するといった活用ができます。
今回は、そんなVary for Traits機能を使用する方法を紹介します。
画面サイズの定義を知る
Vary for Traits機能は画面サイズの定義ごとにレイアウト設定を変更するので、使用する前に、まずは画面サイズの定義を知ることが必要不可欠です。
画面サイズの定義は、横幅と縦幅のw(Width)とh(Height)、サイズの大小のR(Regular)とC(Compact)、の二つの概念の組み合わせでできています。
以下の画像はInterfaceBuilderでiPhone 11 Pro Maxの縦向き状態でViewを表示した際のスクリーンショットです。
左下に、View as: iPhone 11 Pro MAX(wC hR)と書かれています。
iPhone 11 Pro Maxを縦向きにしている状態の画面サイズはwC hR、つまり横幅が小さく、縦幅が大きい端末と定義されていることがわかります。
ちなみに、それぞれの端末がどのように定義されているかは以下の表に起こしたので、参考にしてください
| w | h | |
|---|---|---|
| iPhone(縦) | C | R |
| 4s・SE・8・11 Pro(横) | C | C |
| 8Plus・11・11 Pro MAX(横) | R | C |
| iPad(縦横両方) | R | R |
縦向きのiPhoneのwC hR、横向きのiPhoneがhC、iPadのwR hRなどはよく使うので覚えておくと良いでしょう。
Vary for Traitsを使う
それぞれの端末のサイズ定義がわかったところで実際にVary for Traits機能を使用してみましょう。
準備
例として、まずは画面の中心に横幅300×高さ400の制約を設定したViewを配置します。
その状態で画面を横向きに変更すると、画面自体の高さが400以下になってしまうので、画面から高さ400の制約を設定したViewが見切れて表示されてしまいます。
この状態からVary for Traits機能を使って、画面が横になった場合にレイアウトを変えていきます。
定義したい画面サイズを選択する
早速、Vary for Traitsのボタンをクリックすると、以下の画像の吹き出しが現れます。
WidthとHeightのチェックボックスは、現在表示しているInterfaceBuilderで選択されている画面のサイズ定義で個別に設定したいものにチェックを入れます。
現在表示している画面はiPhone 11 Pro Maxの横向きなので、画面サイズの定義はwR hCです。
両方にチェックを入れるとwR hCの組み合わせのである、8Plus・11・11 Pro MAXの横向きで表示した際に、有効になるレイアウトを設定できます。
Widthのみにチェックを入れた場合はwRが指定されている、横向きの8Plus・11・11 Pro MAXとiPadで表示した際に、有効になるレイアウトを設定できます。
Heightのみにチェックを入れた場合はhCが指定されている、横向き状態のiPhoneで表示した際に、有効になるレイアウトを設定できます。
今回の場合、iPhoneの横向きで表示した際にViewが画面外にはみ出してしまうので、Heightの方にのみチェックを入れます。
これでhCの画面サイズのみで有効になるレイアウトが設定できる状態になりました。
特定の画面サイズでレイアウトを設定する
1.制約の数値を変更する
まずは、Viewの高さの制約を変更してみましょう。
高さの制約の設定を確認すると以下のようになっています。
この中のConstantの左側の+をクリックすると、以下の画像の吹き出しが出ます。
そのままAdd Variationをクリックします。
そうするとConstantの入力欄の下にhCの欄が追加されるので、そこに250を設定してみます。
そうすると、Viewの高さがちゃんと画面内に収まるようになりました。
hCでの数値を変更したので、もちろん縦向きに変更しても影響はありません。
2.制約の有効・無効を設定する
次は横向きの時には、赤いViewの中央揃えではなく、左上に配置するように設定してみましょう。
先ほどのように、View.Center Yの制約を選択し、今度はInstalledの横の+をクリックして、吹き出しのAdd Variationをクリックします。
すると、Installedの下にhC用のチェックボックスが追加されるので、チェックを外すと、制約が無効化されます。
同じようにView.Center Xの制約もhCのInstalledのチェックボックスを追加して、チェックを外しておきましょう。
すると、以下の画像のような状態になるので、ここから新たに制約を設定していきましょう。
今回は左上に配置するので、赤いViewのTopとLeadingに各10ずつの制約を設定します。
設定したView.Leadingの制約の詳細を見てみると、Installedのチェックが外れていて、hCの方のInstalledはチェックが入っています。
つまり、Vary for Traits機能を使用している時に、新たに設定した制約はVary for Traitsボタンをクリックしたときに表示された吹き出しでチェックを入れた画面サイズでのみ有効になるということです。
(今回は、Heightに選択を入れていたので、hC時にのみ有効になる制約ということになります。)
そして、制約の一覧で現在表示している画面サイズで有効な制約はアイコンが明るく表示され、無効な制約はアイコンが暗く表示されるので、それでチェックすることもできます。
この設定が完了すれば、横向きの画面で以下のような表示になります。
3.Viewの背景色の変更を設定する
次に横向きの時に、赤いViewの背景色を別の色にしてみましょう。
今度はViewを選択して、Bacgkroundの横の+をクリックしてAdd Variationをクリックします。

hC用の背景色設定が表示されるので、適当な色を設定すると、横向きの時にのみその色になります。

4.特定のViewを消去・配置する
次は、Viewの上のラベルを設定しましょう。
ラベルには、「300(w)×400(h)」と記載されていますが、横向きの時には、Viewのサイズが300(w)×250(h)なので、「300(w)×250(h)」に変更したいところですが、UILabelのTextは、Vary for Traits機能で差し替えることはできません。
なので、今回の場合は「300(w)×400(h)」のラベルをhCの時に消去して、「300(w)×250(h)」と記載されたラベルをhCの時にのみ表示されるようにすれば望んだ通りの表示になりそうです。
まずは今までの手順と同じように「300(w)×400(h)」ラベルの詳細から、hCのInstalledのチェックを外します。
あとは、新たにラベルを追加します。
制約を追加した時と同じように、新たに追加された「300(w)×250(h)」LabelはhCでのみInstalledになります。
制約と同じようにViewもInstalledかどうかをアイコンの明暗で確認できます。
5.Vary for Traitsを終了する
Done VryingをクリックするとVary for Traitsを終了することができます。
6.確認する
InterfaceBuilderのOrientationを変えて確認してみましょう。

まとめ
Vary for Traits機能を使うことで、縦画面と横画面それぞれに対応したレイアウトを作成する方法を紹介しました。
自分もこの機能を知るまでは、Viewの比率の制約や、制約のPriorityを細かく設定したり、コードで画面サイズや方向で制約を操作して、複数の画面サイズに対応していましたが、この機能を使うことで、コードを使うことなく、制約もシンプルな形で想定している表示を実現できたので、皆さんも使ってみてはいかがでしょうか?

