iPhone5sまでiOS開発の端末対応は非常にシンプルでしたが、iPhone6とiPhone6プラスが発売された現在、iOS開発でも対応する端末の種類が多くなりました。また、6の4.7インチと6プラスの5.5インチ端末は3.5インチ端末の整数倍ではなくなりました。今までの作り方だと、例えばiPhone・iPod TouchとiPadの両方を対応する場合(いわゆるユニバーサル版の場合)、それぞれのレイアウト(IBで作る場合storyboardかxib)を作らないといけませんでしたが、更に4.7インチと5.5インチでその作業を行うと作業時間が膨大になり、レイアウトによるバグも起きやすくなります。この作業が発生しないようにアップルはiPhone6と6プラスの発売と同時に改善策を提供しています。それがSizeClassesという新しい作法です。
対応 | 実装方法 |
---|---|
従来の複数サイズ端末対応 | iPhoneとiPad用それぞれstoryboard・xibを作る |
SizeClassesを使った複数サイズ端末対応 | 一つのstoryboard・xibで統一 |
サンプル1(基本の使い方)
早速SizeClassesを使ってみましょう。 前提条件として、Xcodeのバージョンが6であることが必須になります。 Xcode6を起動して、MenuでFile>New>Projectをクリックして、Single View Applicationのテンプレートを選びます。プロジェクトオプションの入力画面のDevices でUniversalを選択してプロジェクトを作成します(図 1)。今回はSwiftではなくLanguageをObjective-Cにしました。
Main.storyboardを開いてみると正方形のViewが用意されました。Viewの下に「wAny hAny」が見えます。それをクリックすると図2のような9マスの画面が表示されます。どのマスにをクリックするかで、WidthとHeightの変更が行えます。
WidthとHeightはそれぞれCompact、Any、Regularの3種類から選ぶことができます(その組み合わせによって合計9種類を選択することができます)WidthとHeightの一つの組み合わせが複数の端末・向きの集合を指しています。 例えば、Width:Any、Height:CompactはすべてのiPhone・iPod Touchの横向きを指します。WidthとHeightの設定によりサイズの切り替えを行います。 表1がWidthとHeightの組み合わせとそれぞれ対応する端末の一覧となります。
せっかく一つのstoryboardで様々なサイズの端末を対応できるようになりましたので、すべての端末・向きで表示できるUIを作ってみましょう。「wAny hAny」の状態でViewの四隅にそれぞれ一つのUILabelを置きます(図3)。
iPhone6プラスのシミュレーターで実行して見ると、図4のように表示され4つのラベルが全て表示されていないです。
この原因は、制約(Constraint)を追加していないために起きている現象です。ちなみに横向きで右側のLabelと縦向きで下のLabelが中途半端の場所に表示されてしまう原因は、「wAny hAny」の場合のViewのサイズが600×600で(図5)、iPhone6プラスのスクリーンのポイント数が414×736の為です(端末のポイント数についてここを参考)。
では、4つのラベルにそれぞれ制約を掛けていきます。
左上のラベル:Top Layout Guideの下部と0ポイント離れる、親ビューのLeadingと0ポイント離れる(図6)制約。注意点として、マージンが必要なければConstrain to margineを外すこと(ここを参照)。
同様で残り3つのラベルにそれぞれ制約を掛けます(図7)。
iPhone6プラスのシミュレーターで実行してみると、storyboardで設定したとおり表示されています(図8)。
iPadでも4つのラベルが四隅にあるように表示されます(図9)。
ちなみにシミュレーターで起動しなくても各種サイズの端末での表示を確認する方法があります。Xcode右上に2つの丸が重なるアイコン(図10)をクリックして、Previewを選択すると、デフォルトでiPhone 4インチのプレビューが表示されます。図10の左下のプラスアイコンをクリックすると、他の端末を追加することができます。
横向きの端末を見たい場合、端末下部の端末名の左にマウスオーバーすると、回転アイコンが表示されます。クリックすると回転した様子が見えます(図11)。
以上SizeClassesを使って一つのstoryboardだけですべての端末に表示できることを検証しました。
サンプル2(特定の条件の時だけ別の表示を行う)
次に特殊な端末・向きで違うレイアウトを作成してみます。
iPhone6プラス横向き以外すべて同じレイアウト、iPhone6プラス横だけ違うレイアウトにします。
Single View Applicationをもう一つ新規作成します(図12)。
Main.storyboardを開いて、「wAny hAny」のままで、Viewに3つのボタンを追加します(図13)。
3つのボタンとも選択して、Top Layout Guideと0ポイントの制約、横幅が同じ、同じ縦横比の制約を追加します(図14)。
一番左のボタンを選択して、Super ViewのLeadingと0ポイントの間隔、一番右のボタンを選択して、Super ViewのTrailingと0ポイントの間隔の2つの制約を追加します(図15)。
真ん中のボタンを選択して、左右のボタンと0ポイントの間隔の制約を追加します(図16)。
3つのボタンを選択してUpdate Framesをクリックすると、3つのボタンが一番上に並ぶようにレイアウトされました(図17)。
見やすいように3つのラベルのスタイルを図18のようにカスタマイズします。
シミュレーターで実行して見ると、iPhone6プラスの横向き以外予想通り、画面の一番上に3つのボタンが均等に表示されます(図19)。
サイズを「wRegular hCompact」に切り替わります(図20)。5.5インチiPhoneが横向き場合のサイズです。
ここからがポイントです。「wAny hAny」で追加した制約を全部選択して、右側ユティリティエリアに4つ目の「Show the Attributes inspector」を表示して、Installedの左側の+ボタンをクリックします(図21)。
Regular Width> Compact Heightを選択して、「wR hC」をインストールします(図22)。
「wR hC」ところのチェックを外します。そうすると「wR hC」サイズにある制約が全部無効になります(図23)。
「wR hC」のサイズに3つのボタンに対して制約を追加し直します(図24)。
シミュレーターでiPhone6プラスの端末を実行して見ると、横の場合他のサイズと違うレイアウトで表示されることが確認できました(図25)。
まとめ
・開発を始める際には「wAny hAny」から開発を始め、まずは全端末に適用する形でレイアウトを作成するのがオススメ!その後特定の端末で別の表示方法をしたいときには対象のレイアウトで別の表示方法を構築すればよい。 ・SizeClassesを使う場合AutoLayout(制約)が必須になるので注意が必要。 ・シミュレーターを起動しなくてもプレビューを使えば各端末での表示を確認することができるのでとても便利
補記
サイズ毎に追加・削除できるのは下記3種類です。
・UIView
・制約
・フォント(現時点UILabel、UITextField、UITextView、UIButtonの4種類だけ) AndroidのWrap Contentに相当する機能はまだないようです。