Autolayout

AutolayoutはiOSエンジニアならばIBOutletとIBActionとセットで身につけておくべきことの一つです。

なぜAutolayoutが必要なのか

iPhoneアプリを作るのに、iPhone8とかiPhone8sでは問題なくても、iPhone8Plusとか大きい画面でアプリを起動すると、画面が崩れるとか嫌ですよね。
というか、そういうアプリはApp Storeにアプリを公開する審査に通りません^^;
なので、アプリを起動したとき、画面の大きさが違う端末でも同じように表示できるようにするのがAutolayoutです。

本項ではAutolayoutの以下のことを説明していこうと思います。

他のUIの位置を基準にUIの位置を設定する(マージンを設定する)

他のUIの位置を基準に、指定したUIの位置を設定できます。これはUIのマージンを設定することで実現できます。
図にすると以下のような感じです。

なぜこれが必要かと言いますと以下のことが考えられます。

  • フッターなど常に画面の下に表示しておきたいUIを作りたい
  • ベージ上部に表示するタイトルのUIなど、画面いっぱいに表示したい

どう設定するかというと、Storyboardの画像のココをクリックすることで設定できます。

setalign_01

すると以下の画面が表示されます。
今回、指定したUIのUIとの間隔を設定するので、画像の赤枠で囲んだところを設定します。

setalign_02

こうすることで、画面の大きさが変わっても、他のUIの位置を基準に、UIの位置を設定することができます。
以下が実行結果です。
例えばこんな風にUIを設置したとしましょう。
(太鼓の達人のアイコンが役に立ってますw)

setalign_03

そして、ラベルと画像の位置を設定します。
画像に関してはUIImageViewの項目を参考にしてください。

まず、マージンを設定しない場合はどうなるのかを見てみましょう。
iPhone6sではイメージ通りですが、iPhone5sの時は下に切れてしまっていますね。それに、画面の中央より少し右に位置しています。

iPhone5s iPhone6s
set_align_iphone5s set_align_iphone6s

では、実際に設定してみましょう。
まず、画像に関してです。
左右と下のマージンを以下のように設定します。
今回は、幅と高さも設定しています。
margin_img

そして、ラベルに関しては上下左右のマージンを以下のように設定します。
margin_label

これでさっきと同じように、iPhone5sとiPhone6sで実行した結果を比較して見ましょう。

iPhone5s iPhone6s
set_align_iphone5s_after set_align_iphone6s_after

どうでしょう?
今回はきちんと画面にラベルも画像も収まっていますよね!
このように、「画面の大きさが違くても、変わらないようにレイアウトを作成していきたい」という時にAutolayoutがとても役に立ちます。
しかし、今度はラベルの文字列が途切れていたり、画像が縦に伸びてしまっていますね。
次は、大きさが変わらないために、幅や高さ、アスペクト比を設定して見ましょう。

ちなみに、今回のように、
ラベルの上マージンを設定する時に、ラベルの上にUIがある場合はラベルとその上にあるUIとのマージンが設定されます。
ラベルの左、右、下のマージンを設定する時に、ラベルの左、右、下にUIが何もない場合、画面端とのマージンが設定されます。

指定したUIの高さ、幅、縦横比(アスペクト比)を設定する

次は高さ、幅、縦横比を設定します。

高さ・幅

文字や画像の関係上、画面の大きさに関わらず同じ大きさで表示したいということがあるでしょう。
そのような時は、以下の場所で設定できます。

ui_size_01

マージンを設定してしまうと、場合によってはUIが横や縦に伸びることがあります。
例えば、以下のようにマージンを設定します。
ui_size_02

その時の実行結果はこちらです。
ui_size_02_exe

画像の高さが変わっちゃいますね。
本来は、大きさが変わらないで欲しいのに。
なので大きさを固定するには、Autolayoutを使って高さと幅を固定してあげます。
こんな感じに。
ui_size_02_exe_02

すると、画面の大きさが変わっても同じ大きさで表示されていることがわかります。(まあ、解像度の関係で見た目小さく見えることもあるかもしれませんが)
ui_size_02_exe_03

しかし、今度は「中央からずれてる…」と思う人が出てくるでしょう。
そこは、指定したUIの中央の位置を画面の中央の位置を基準にして設定するで説明します。

アスペクト比

つまりは縦横比です。
これを設定すると便利なことがあります。
「UIの大きさは固定したくない。でも、UIの縦横比は固定したい」という時に使えます。
例えば、「画像の縦横比を固定したまま、可能な限り画面いっぱいに表示したい」という時です。
(余談ですが、これはNSLayoutConstraintを使ってコードから修正できないので、注意が必要です。)

どこで設定するかといいますと、以下の部分で設定ができます。
aspect01

すると、アスペクト比を維持したまま画像が大きくなったり小さくなったりしています。
マージンを設定しただけは縦長になってしまいましたが、アスペクト比を設定してあげることでそれを防ぐことができました。
画像を表示する上では重宝されるでしょう。

iPhone5s iPhone6s
aspect_iPhone5s aspect_iPhone6s

指定したUIの高さ、幅を他のUIを基準にして設定する

さて、高さと幅を固定することもできました。
もう少し高さと幅に関して踏み込んでみましょう。

時には、「このUIとこのUIの高さや幅を揃えたい」というときがあるでしょう。

その時はこのように設定します。
まず、幅、高さを揃えたいUIを選択します。

そして、ここにチェックを入れます。

こうすると、UIの幅や高さを同じにすることができます。
実行してみると、確かに同じ幅になりました。

また、ここから設定すると、「このUIよりこれくらい大きい高さ(または幅)にする」ということもできます。

では、実際にやってみましょう。
その時の実行結果がこちらです。
たしかに、微妙に大きくなっているのがわかりますね。

指定したUIの中央の位置を画面の中央の位置を基準にして設定する

これはいたってシンプルです。
指定したUIを中央におきたい時に使います。
設定はいたって簡単。
UIを選択して、以下の設定をしてあげるだけです。


これで設定完了です。
ちなみに、設定していないときと設定した時の違いです。
設定なし

iPhone5s iPhone6s

設定あり

iPhone5s iPhone6s

そして、さっきと同じように、ここの値を操作してあげるだけで
「中央からこれだけずらしたところに配置する」
という設定ができます。

指定したUIの中央の位置を他のUIの中央の位置を基準にして設定する

これはさきほどの「指定したUIの中央の位置を画面の中央の位置を基準にして設定する」の基準にする位置が、画面の中央から他のUIになるだけです。

指定したUIの上下左右どれかの位置を、他のUIの上下左右どれかの位置を基準にして設定する

これもここまできてしまえば簡単です。
先ほどは、UIの中央の位置を、他のUIの中央の位置を基準に設定しましたが、
今度はUIの上下左右端を基準に位置を設定します。