iOSのAuto Layout

# はじめに
Merry Christmas! 

皆さんがこの記事を読んでいるときに、僕が海外にいるかもしれませんが!!!

これは [ドリコムAdventCalendar](http://www.adventar.org/calendars/518) の25日目です。最後の日です。
24日目は、[@hayato240](http://qiita.com/hayato240/private/8bae51960cf10ea787e7)です

# 自己紹介
はじめましてタイのサトシです。2013年４月新卒で入社しました。
iOS開発が好きです。趣味は海外旅行と映画を見ることです。

現在は担当しているチームでiOSエンジニアをやっています。

iOSアプリの開発経験は１年未満なので、先輩方々から様々な知識を学んでいます。
iOS開発の中ではいろいろなことを学んでいますが、最近自分が学んでいるAuto Layoutを
簡単に紹介したいと思います。

# 本題
## Auto Layoutとは

Auto Layoutはアプリケーションのユーザインタフェイスを作成するシステムで、制約 (Constraint) に基づいてviewとの関係を作成したり、viewと自分のsuperviewを関連付けたりすることができます。Auto Layoutを導入することによって、画面の大きさや向きの違いに応じて動的に変化する、汎用的な画面レイアウトを作ることができます。
![xcodeview](https://qiita-image-store.s3.amazonaws.com/0/55799/d5abbba3-b476-31a0-b03d-eed45a33d417.png)

## Auto Layoutの特徴
Apple資料に書いてあるAuto Layoutの特徴は以下のようになります。

* 必要に応じていつでも制約を追加できる
* Ctrlキーを押しながらドラッグする操作、またはメニューコマンドにより、簡単に制約を追加できる
* 制約とFrameをそれぞれ独立に更新できる
* 動的に配置が決まるビューに、プレイスホルダ制約を指定できる
* 相反する制約、配置がひと通りに決まらないビューなどの問題は、状況を視覚的に確認しながら
解消できる

## Auto Layoutの考え方
Auto Layoutで使っているのは制約(Constraint)という考え方です。これはインタフェイスを構成する要素のレイアウト（配置）を決める規則です。
ある要素の幅や高さを指定する制約、他の要素からの左右のmarginなど指定する制約があります。実行時に指定した制約と画面の大きさに基づいて、画面のレイアウトが動的に変化されます。

また、Xcode6からSize Classesが導入されました。Size Classesを使うことによって一つのビューだけで端末ごとにAuto Layoutを簡単に作成することができます。
![スクリーンショット 2014-12-21 23.03.15.png](https://qiita-image-store.s3.amazonaws.com/0/55799/bfd39ffd-6236-68a5-b9dc-336d85895fb5.png)

### 制約に関する基本事項
制約を指定するために以下のように基本の項目があります。

属性:left、right、top、bottom、leading、trailing、width、height、centerX、centerY、baseline

属性leadingとtrailingは、左から右へ書く言語の場合はleftおよびrightと同じですが、に右から左へ書く言語ならばleadingおよびtrailingとright
およびleftと同じ意味になります。

制約には以下のプロパティがあります。

* 定数値 (Constant value)
 　ポイント単位の大きさ
* 関係 (Relation)
 　ビューの属性値として、定数値以外関係式も設定することができます。
* 優先度 (Priority level)
　制約には優先度を指定することにより、優先度の高い制約をまず満たした後で、優先度の低い制約を反映するとなっています。

## Interface BuilderでAuto Layoutを指定する
Auto Layoutを指定する方法はコードとInterface Builderがあります。今回は例としてInterface BuilderでAuto Layoutを指定する方法を紹介します。

Xcode6以上でnibファイルまたはstory boardを作成すると、自動的にAuto LayoutとSize Classesが設定されています。 
![スクリーンショット 2014-12-21 23.11.43.png](https://qiita-image-store.s3.amazonaws.com/0/55799/c22066ef-94bc-e6de-c292-381a11889e3c.png)

以下の画像の下に書いてある「wAny hAny」のSize Classesで設定されています。この状態でビューを作成すると全ての端末(iPhone、iPad)が同じレイアウトになります。
![スクリーンショット 2014-12-21 23.15.40.png](https://qiita-image-store.s3.amazonaws.com/0/55799/f83cd2d4-c349-0b6a-7e7b-cc496aa1f0cb.png)

XcodeのAuto Layoutツールを説明します。

![スクリーンショット 2014-12-21 23.10.29.png](https://qiita-image-store.s3.amazonaws.com/0/55799/7e804833-cfb3-f78f-d589-78cab4f7e5e8.png)

* Align 揃えに関する制約を指定します。コンテナの中央に寄せる、2つのビューの左辺に揃える、などができます。
* PIN 空間的レイアウトに関する制約を指定します。ビューの高さを定義する、別のビューからの水平距離を指定する、などができます。
* Issues。レイアウトの問題を解決するためのコマンドで、どのような制約を追加・削除すればよいか、候補が現れます
* Resizing 大きさが変わったとき、制約にどのような影響を及ぼすか、を指定します。

## 例
今回以下の画像のようにAuto Layoutでビューを作成します。

![スクリーンショット 2014-12-22 7.49.24.png](https://qiita-image-store.s3.amazonaws.com/0/55799/d5225333-07fe-1c55-4bcf-fd0e42bd54ea.png)

### 制約
上の画像のようなビューを作成するために、以下の制約を指定する必要があります。

* 左右のMarginが100pxの固定で、画面の幅によりビュー（青・黄色）の幅が動的に変更
* iPadの画面の高さがかなり広いのでiPadのみビューとの下Marginを最も多くする
* iPadのビューだけで別のビュー（ピング）を追加し、真中に配置する

1.まず 左右のMarginが100pxの固定で、画面の幅によりビュー（青・黄色）の幅が動的に変更する制約を指定する

　class sizeがwAny hAnyの状態で４つビューを作成し、幅が400で高さが50を設定します。一番上のビューにxが100yが183の設定を追加し、残りのビューにxが100yが上のビューから 13pxの設定します。フレームの設定が終わったら、Auto Layoutを設定します。必要な制約は高さ、左、右、上になります。

![スクリーンショット 2014-12-22 8.20.34.png](https://qiita-image-store.s3.amazonaws.com/0/55799/34715a62-6807-2d97-be29-e45844f1233d.png)

Auto LayoutツールからPinメニューを選択し必要な制約を設定し、「Add 4 Constrains」ボタンを押します。残りのビューも同じのように設定を行いますが、上のMarginが183ではなく13になります。




2.iPadのみでビューとの下Marginを最も多くする制約を指定する。
　まず、下に書いてある「wAny hAny」のSize Classesを押して以下の画像のように
iPadのSize Classesを選択すると「wRegular hRegular」に変更されいます。。この状態でビューのフレームや制約を修正しても、iPhoneのレイアウトに影響がありません。

![スクリーンショット 2014-12-22 8.27.50.png](https://qiita-image-store.s3.amazonaws.com/0/55799/e979aa0e-2d68-b9d8-c544-c754766afbfd.png)
一番上のビュー以外を選択し、右側のSize inspectorにあるTop Spaceの制約の「edit」ボタンを押し70を入れると、ビューの制約とフレームが更新されます。

![スクリーンショット 2014-12-22 8.40.10.png](https://qiita-image-store.s3.amazonaws.com/0/55799/5534a855-ab18-be83-2290-361cb0f3d9dc.png)


3.iPadのビューだけで別のビュー（ピング）を追加し、真中に配置する制約を指定する
「wRegular hRegular」のSize Classesのままで200x50のビューを追加します。
 
 Pinから以下のように制約を追加します。制約を追加したら、Warningやエラーが出るかもしれないのでとりあえず無視します。
![スクリーンショット 2014-12-22 8.51.22.png](https://qiita-image-store.s3.amazonaws.com/0/55799/f492f0ed-aebc-3661-78ca-1f44bde48426.png)
次、真中に配置するためにAlignからHorizontal Centerの制約を指定します。
![スクリーンショット 2014-12-22 8.50.28.png](https://qiita-image-store.s3.amazonaws.com/0/55799/923a5ac8-18bb-d3e7-9f19-87b7cdaffafa.png)

制約の指定が終わったらまだ出ている場合、それを直します。例えば
以下のWarningは実際のフレームと制約が合ってないということがわかりました。

![スクリーンショット 2014-12-22 8.52.12.png](https://qiita-image-store.s3.amazonaws.com/0/55799/c7f4f9f7-7265-2d07-53dd-3105663e537d.png)

そのWarningアイコンを選択すると、解決する方法が表示されます。
今回は、制約の設定が合っているので実装のプレームを制約に合わせるため、
Update Frameを選択します。
![スクリーンショット 2014-12-22 8.52.21.png](https://qiita-image-store.s3.amazonaws.com/0/55799/33a3d11b-233a-81f1-7b10-916aacbebc30.png)

ここまで、Warningやエラーなのどがなければ制約指定が完了です。

# まとめ

Auto Layoutの機能を簡単に紹介しました。

AppleがAuto Layoutを導入することによって、ビューを作成するのがより楽になりました。

Auto Layoutを使うことにより、画面の大きさや向きの違いに応じて動的に変化するレイアウトを簡単に作成することができます。しかし、使い方によってAuto Layoutをうまく使えない場合もあります。

本題で説明した以外にまだいろいろなAuto Layoutの使い方があるので、
興味がある方がいたら、是非調べてみてください。

以上です。

皆さん、良いお年を!　Merry Christmas And Happy new Year 2015!!


#　参考資料

https://developer.apple.com/jp/devcenter/ios/library/documentation/AutolayoutPG.pdf