ケースからAutoLayoutを学ぶ

# はじめに

[よくわかるAuto Layout iOSレスポンシブデザインをマスター](https://www.amazon.co.jp/%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8BAuto-Layout-iOS%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B7%E3%83%96%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%92%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC-%E5%B7%9D%E9%82%89-%E9%9B%84%E4%BB%8B/dp/4865940324)を参考に、AutoLayoutで学んだことを記事にしていきたいと思います。今回はケースからAutolayoutを学んでいきたいと思います。


# ケース1 同一幅のオブジェクトを並べるケース

以下のように、Buttonを3つ均一に並べる

<p align="center"><img width="200" alt="Simulator Screen Shot 2016.07.18 15.36.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/f5837f59-9ec8-d7d9-45d6-9d167b2459a9.png"></p>


## 大まかな手順

１. `ContainerView`の配置
２. `Button`を3つ配置
３. 制約を追加

`Button`をグループ化するために親となる`ContainerView`(`UIView`)を作成し、入れ子にする。

<p align="center"><img width="139" alt="スクリーンショット 2016-07-18 15.37.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/4736642c-130d-0bad-7fcd-e9b14ea25ffd.png"></p>

## 制約について

**水平方向**

`ContainerView`

１. `ContainerView.leading = leading`
２. `trailing = ContainerView.trailing`

`Button`

３. `Button1.leading = leading + 5`
４. `Button2.leading = Button1.trailing + 5`
５. `trailing = Button3.trailing + 5`
６. `Button3.leading = Button2.trailing + 5`
７. `Button2.width = Button1.width`
８. `Button3.width = Button1.width`

`ContainerView`は画面幅に固定してあり(1, 2)幅は決定しているので3つのボタンの幅を等しくし(7, 8)、水平方向の制約をつけることで(3~6)、`Button`の幅が決定する

**垂直方向**

`ContainerView`

１. `ContainerView.centerY = centerY`

`Button`

２. `Button1.top = top`
３. `bottom = Button1.bottom`
４. `Button2.centerY = centerY`
５. `Button3.centerY = centerY`

垂直方向の制約はこれだけで良い。なぜなら`Button`の高さ（幅）はテキストとFontによって決定されるからである。よって2, 3の制約によって自然と親の`ContainerView`の高さも決定する。1. によって垂直方向の制約は画面の中央に設定されているのでここで垂直方向の制約が決定する。`ContainerView`の高さが決定しているので(4, 5)によって`Button2`, `Button3`の高さも決定する。
これが見落としがちで高さの制約を余分に追加してしまうケースが多い。余分な制約はバグの温床となる。意図的に`Button`の高さを決定したい場合は`ContainerView`の高さを決定すれば変更できる。

## 制約の全体像

<p align="center"><img width="354" alt="スクリーンショット 2016-07-18 15.51.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/26fac3ed-6722-a6c7-8b0d-0ec447505526.png"></p>

# ケース2 等間隔で並ぶオブジェクト

以下のように、Buttonを3つ均一に並べ、等間隔に配置する

<p align="center"><img width="200" alt="Simulator Screen Shot 2016.07.18 16.10.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/b5a60124-557d-cb08-611c-67d5efa139e6.png"></p>

## 大まかな手順

１. `ContainerView`の配置
２. `Button`を3つ配置
３. 間隔のために用いる`View`の配置
４. 制約を追加

一つ目と手順は大まか同じだが、今回は等間隔に配置するためのViewを用意する。(`Space1`, `Space2`)

<p align="center"><img width="162" alt="スクリーンショット 2016-07-18 16.12.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/3b26d945-0679-fd98-09c3-0181e35d3f12.png"></p>

## 制約について

**水平方向**

`ContainerView`

１. `ContainerView.leading = leading`
２. `trailing = ContainerView.trailing`

`Button`

３. `Button1.leading = leading + 5`
４. `Space1.leading = Button1.trailing`
５. `Button2.leading = Space1.trailing`
６. `Space2.leading = Button2.trailing`
７. `Button3.leading = Space2.trailing`
８. `trailing = Button3.trailing + 5`
９. `Space2.width = Space1.width`
１０. `Button2.width = Button1.width`
１１. `Button3.width = Button1.width`

ケース1とほとんど同じだが今回は、4~7の制約によってButtonの間の幅は`Space1`と`Space2`の幅にしている。これに加えて9の制約で`Space1`と`Space2`を同じ幅にすることによって等間隔な幅が計算されて水平方向の幅が決定する。

**垂直方向**


`ContainerView`

１. `ContainerView.centerY = centerY`

`Button`

２. `Button1.top = top`
３. `bottom = Button1.bottom`
４. `Button2.centerY = centerY`
５. `Button3.centerY = centerY`
６. `Space1.centerY = Button1.centerY`
７. `Space2.centerY = Button1.centerY`
８. `Space1.height = 1`
９. `Space2.height = 1`

垂直方向の制約はケース1とほとんど同じである。異なる部分は7~9によってSpaceの垂直方向の制約を決定しているところである。
`Space1`と`Space2`は間隔を決定するためだけのViewなので色は透明色を設定する。しかし、***透明色を設定する場合は、透過処理が入り描画パフォーマンスは落ちる***ため、背景色が決まってる場合は背景色を設定したほうが良い。


## 制約の全体像

<p align="center"><img width="320" alt="スクリーンショット 2016-07-18 16.23.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/40fda084-f8e1-f3ef-1fd3-7e0b0eacc288.png"></p>