2015年10月2日金曜日

AutoLayout 超入門

概要

AutoLayout はサイズの異なるデバイス間でもレイアウトを自動で調整することで綺麗に見せる機能です
Xcode の InterfaceBuilder を使って設定する方法を紹介します
Android で言うところの RelativeLayout 的な機能です

環境

  • Mac OS X 10.10.5
  • Xcode 7.0.1

サンプルプロジェクト作成

Xcode を開いてサンプルプロジェクトを作成します

  • Fire -> New -> Project
  • Single View Application
  • Choose options for your new project は適当に決定してOK
  • プロジェクトの保存先を適当に決定

これでOKです
配布するアプリではないので、AppID とかは気にしないでいいと思います

Main.storyboard を開く

左メニューから Main.storyboard をクリックして開きましょう
とりあえず View Controller が 1 つあると思います
今回はこれをそのまま使っていきましょう
open_xib.png

UIコンポーネントを設置する

View が 1 つあるのでそれに Label の UI コンポーネントを 3 つ配置しましょう
set_3_label.png

とりあえずこんな感じになればOKです
3 つの UI コンポーネントを重ねて設置しないように注意しましょう

あと AutoLayout の効果がわかるように適当に背景色を指定しておきましょう
set_background.png

constraints を設定する

さて、ここからが本題です
この constraints (制約) という機能が AutoLayout の正体といってもいいでしょう

まず一番上の Label から設定していきましょう
Label を選択した状態にし、右下にある 4 つ並んだアイコンの右から 2 番目を選択します
すると吹き出しみたいなやつが出てきて constraints を設定できます
これで何ができるのかというと、他のUIコンポーネントとのマージンや配置場所を設定することができます
マージンを設定する場合は

  • 赤い点線になっている部分をクリック
  • 赤い実線になる
  • プルダウンからマージンの基準となる他のUIコンポーネントを指定
  • 距離を設定

という手順になります(これが非常にわかりづらい、あと点線を実線にしたり、他にフォーカスがあたると指定した数字が戻っちゃったりする、、)

とりあえず一番上のラベルは以下のような感じで設定しました
set_constraints.png

隣接するコンポーネントとはそれぞれ 10 マージンするという設定になります
これで良ければ一番下の Add 4 constraints をクリックします
すると左メニューに constraints が追加されます
added_constraints.png

こんな感じで他の Label も設定しましょう
最終的に以下のような constraints の設定にしました
set_all_constraints.png

急に複雑になった感がハンパないですが、落ち着きましょう
一番初めの Label にした上下左右の 10 のマージンの設定を他の Label にもやっただけです

フレームを更新する

constraints を設定したらその設定を InterfaceBuilder に反映させてどう見えるか確認することができます
4 つ並んでいるアイコンの一番右をクリックし「Update Frames」を選択しましょう
update_frame.png

すると作成した constraints にしたがって UI コンポーネントが整理されます
たぶん今回の設定だと以下のようになると思います
updated_frames.png

最後のラベルが異様な高さになっていますが、今回は各コンポーネント間のマージンだけを設定しました
具体的に高さを決めていません
この場合、先にマージンが決定されそれに応じて各UIコンポーネントの高さが決定します
上に配置したコンポーネントから先に評価され最後のラベルのコンポーネントが最後に評価されたため余った高さ分がコンポーネントの高さに割り当てられたことになります

動作確認

では動作確認してみましょう
適当にシミュレータを選択してビルドしましょう

まず Portrait (縦向き) の場合ですが、これは InterfaceBuilder で確認していた通りの感じだと思います
横まできっちりラベルが伸びており、縦は最後のラベルの高さで画面いっぱいまで伸びていると思います
portrait.png

では、次にシミュレータを Landscape (横向き) にしてみましょう
Hardware -> Lotate Left で横向きにできます
すると横幅と縦幅が変化したにも関わらずピッタリ綺麗に表示されていると思います
landscape.png

これが AutoLayout のちからになります
例えばこれが AutoLayout を使わずに決め打ちで width や height を設定していると Landscape にしたときに横幅が足りなくなる現象に見舞われると思います

最後に

InterfaceBuilder だけで設定できるので、使いこなせると非常に便利な機能だと思いました
ただ、操作や設定がやや困難でマスタするまでには少し時間が必要かなと感じました
また、Xcode のバージョンは頻繁にアップデートし、それに伴い UI が変わるので、今回紹介した操作とは、バージョンが違う場合異なる可能性が高いです

自分的にハマったのは隣接するコンポーネント間のマージンの設定です
マージンを設定するときに XCode が自動で判断して隣接するコンポーネントを決めるのですが、それが全然違うコンポーネントだったケースがあったので、それにハマりました

あとは自分は遭遇したことがないですが、1 つの View 上に非常に大量の UI コンポーネントがある場合にそれに 1 つ 1 つ constraints を設定するのは非常に大変で手間のかかる作業になると思いました
そういった場合にはちょっと使えないレベルになってしまうかもしれません

0 件のコメント:

コメントを投稿