【Swift】AutoLayoutでUI部品のサイズを比率で制約したい

# はじめに
現在、Swiftの学習を初めて一ヶ月ほどになり、ちょっとしたアプリを作ってみたりしています。
そこでデバイスサイズにより、レイアウトが崩れてしまうという壁にあたりました。

各デバイスの画面サイズに対応できるようAutoLayoutに挑戦しましたが全然わかりませんでした。
試行錯誤していくうちに、自分の実現したかったUI部品のサイズが画面の高さの比率で変化するやり方をなんとなく理解したのでここに記録します。（間違えていたり、誤認識している場合ご指摘お願いいたします。）

# 開発環境

- macOS Catalina version10.15.7
- Xcode version12.2
- Swift5

# AutoLayoutについて
こちらの記事が大変わかりやすく参考になりました。
[怖くない！AutoLayout 〜多画面対応 with Storyboard〜](https://qiita.com/_ha1f/items/5c292bb6a4617da60d4f)

AutoLayoutではいろいろ設定ができるため、自分のような初学者には難しいので今回必要なもののみに焦点を当てます。

### 今回の重要なもの
こちらの二つ

- Spacing to nearest neighbor
- Equal Heights

`Spacing to nearest neighbor`は直訳すると「最近傍への間隔」ということで近くにある部品との距離を指定することのできるものです。下記画像の箇所で指定します。
各項目の詳細については先ほどの記事を参考にしてください。

![スクリーンショット 2021-01-24 14.53.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/8d8dc22b-620c-52fd-597c-f3c73304af7a.png)

二つ目に重要なものもはこの画像に写っている、`Equal Heights`です。
`Equal Heights`は2つ以上のUI部品を選択した状態のときに使用することができる設定で、選択した複数部品の高さを同じ値に揃えることができます。

これを用いて、画面高さとUI部品をEqualHeightsで設定してあげれば良い。
でも、画面高さと同じだと全然使えないじゃん！と自分は思いました。

安心してください。今回で言えば、画面高さに対して`比率でサイズを指定することができます`。
これを使うことで、画面高さに対して常に50%の大きさにしたい！など実現できます。
※同様にEqualWidthsを使うことで、横幅も比率指定できます！

# やってみる
まずは適当にUI部品（部品Aとします）を設置します。この部品AをSafeArea高さに対して25%の高さにしたいと思います。

![スクリーンショット 2021-01-24 15.10.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/9fe87bd5-d98f-073c-9123-944826c8ac2c.png)


次に、`Spacing to nearest neighbor`を使って、画面上部と左右に対して距離を0とします。
下記画像のように指定したら、`Add 3 Constraints`を押すことで適用されます。

![スクリーンショット 2021-01-24 15.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/5924a50b-b443-3d55-630c-ca308dfa2a09.png)

そうすると、このようにSafeAreaの上部と左右の距離が0、つまり部品Aの幅＝デバイスの幅となります。左の階層部分をみると、`Constraints`というものが追加されています。
これがAutoLayoutで設定した制約です。ここをクリックして設定値を変えたりできます。

![スクリーンショット 2021-01-24 15.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/b33e5e8a-e4ba-ff71-e40e-ee20aac8e82e.png)

次に、`Equal Heights`を用いてSafeAreaと部品Aの高さを同じになるよう設定します。
やり方は、左の階層部分の`Safe Area`と`部品A`を選択（Macならcommandを押しながらクリック）し、`Equal Heights`を設定します。そうするとこのようになります。

![スクリーンショット 2021-01-24 15.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/05bc6e5f-1081-fadf-ab57-84d6d48bcc28.png)

部品AがSafeAreaと同じ高さになったため、このように画面いっぱいに表示されます。
また、階層部分に`部品A（25%）.height = Safe Area.height`という制約が追加されました。

最後にやることは、比率の設定です。今回はSafeAreaに対して25%の高さにします。先ほど追加された`部品A（25%）.height = Safe Area.height`という制約を選択します。

そうすると、下記画像のようにEqual Heights Constraintが表示されるので`Multiplier`の値をみると1となっています。これは、部品AがSafeAreaの高さに対して1.0（100%）の高さ、つまり同じ高さということになっている。この値を0.25(25%)と設定すればOK。

![スクリーンショット 2021-01-24 15.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/904c5d46-fffa-5eba-e13b-3a8251adaaa8.png)

![スクリーンショット 2021-01-24 15.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/600de347-6ec2-6c95-2e81-0c7dbff2c063.png)

無事、SafeAreaに対して25%の高さに設定することができました。
制約部分を見てみると、`部品A（25%）.height = 0.25 × Safe Area.height`としっかり設定ができていることが確認できます。高さの比率を変えたい場合は、先ほどと同様の手順で値を変えることで変更できます。

同様の手順で、他の部品も設置してみましょう。
今回は25%/45%/30%と分けて設置してみました。他のデバイスサイズでも確認してみます。

![スクリーンショット 2021-01-24 15.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/62b5f9c0-b5f2-266f-8cce-e8b47c6178fc.png)
iPhone11

![スクリーンショット 2021-01-24 15.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/26882f23-9d62-4bfc-ca66-b17698d3d127.png)
iPhone4S

こんな感じで、画面サイズが変わっても指定の比率通りにサイズが変更されています。

# まとめ
今回は、AutoLayoutを用いて、UI部品のサイズを比率で制約しました。
引き続きいろいろ触ってみて、AutoLayoutを意のままに操れるよう頑張ります。

以上。