iOS

【Swift4】Auto Layoutが超簡単にできる!「UIStackView」の使い方【iOS】

どうも、Auto Layoutがいまいちよく分からないままAppstoreにアプリをリリースしました、まに(@mani_transm)です。

みなさん、Auto Layout、ちゃんとやってますか?(爆)

僕の方はというと、最初にリリースしたアプリ、「画面サイズごとにStoryboardを作ってそれを初回起動時に場合分けする」という荒技でAutoLayoutを実装した程度には、ちゃんとやれてません()

まに
まに
やっぱちゃんとiOSアプリ作るなら、Auto Layout出来るようにならなきゃなー

と思って調べていたら、Auto Layoutが簡単に実装できる「UIStackView」というものを見つけました。

チュートリアルとして簡単に使ってみたら、これがまぁAutoLayoutが捗る良いものだったので、今回この「UIStackView」についてバチコリまとめていこうと思います!

UIStackViewとは

「そもそもUIStackViewってなんぞや?」ってことで説明すると、UIStackViewは、iOS9以降で使えるAutoLayout用のクラス。

垂直・水平方向に要素をまとめて均等に配置することができる、便利な「」ですね。

このUIStackViewが導入される以前は、Auto Layoutというと要素1個ずつにちまちまと制約(Constraints)をつけていたのですが、

これが使えるiOS9以降になってからは、2つ以上の縦・横に並ぶ要素をUIStackViewでひとまとめにして管理することができるようになったのです。

UIStackViewの中に入れた要素は、UIStackViewのプロパティ値を設定することで配置を決めることができるので、制約(Constraints)をつけるのはUIStackView自身のみでOK。

劇的に制約(Constraints)が減ってスッキリしてますよね!

要素を1個ずつバラバラに配置していたのが、同じ様な要素は「箱」にまとめて位置関係を簡略化することができるのがこの「UIStackView」です。

UIStackViewの使い方

さて、百聞は一見にしかずなので早速UIStackViewを使ってみましょう。

「Storyboardでの使い方」と「コードでの使い方」の2つをそれぞれ解説していきます。

Storyboard

Object Libraryから作る

UIStackViewはUIButtonやUILabelと同じでObject LibraryからD&Dで作れます。

「Horizontal Stack View」は水平方向(横一列)に並べるStackView。

「Vertical Stack View」は垂直方向(縦一列)に並べるStackViewが作れます。

UIStackViewを置いたら、その中に入れたい部品をD&Dしましょう。

入れた部品の配置は、他の部品と同様Attributes Inspectorで設定できます。プロパティのあれこれは後の方で解説してます!

Auto Layoutツールバーから作る

どっちかというと僕はこっちの方が好き。Auto Layoutツールバーからも作ることができます。

まず、UIStackViewでまとめたい要素群を一括選択します。

選択できたら、Auto Layoutツールバーにある「Embed in」のボタンをクリック。

これで選択した要素群が全て1つのUIStackViewにまとめられます。

コード

UIStackViewをコードで作成する場合はこんな感じのコードになります。

ビルドするとStoryboardと同様にStackViewが作れます。

コードで書いてみた感じ、UIStackViewをコードで作るのは、簡単なものなら問題なくできそうだけど、複雑なレイアウトを作ったりコードだけで画面全部のレイアウトを作るとなると結構難しそう。基本Storyboardで作った方が良いかもです。

UIStackViewのプロパティ

UIStackViewが配置できたら、プロパティをいじって中身のレイアウトを整えていきましょう。

UIStackViewで設定できるプロパティはこちら。

  • 要素の配列方向「Axis」
  • 要素の揃え位置「Alignment」
  • 要素の配置方法「Distribution」
  • 要素間に空ける間隔「Spacing」

ちなみにそれぞれの型は、

  • Axis 「UILayoutConstraintAxis」
  • Alignment「UIStackViewAlignment」
  • Distribution「UIStackViewDistribution」
  • Spacing「CGFloat」

です。


Axis … 要素の配列方向

AxisはStackView内の要素を並べる方向を指定することができます。

指定できるのは以下2方向。

  • Horizontal(水平方向)
  • Vertical(垂直方向)

「縦に並べたいか、横に並べたいか、どっちか選べ」って感じですね。

Alignment … 要素の揃え位置

Alignmentは、StackView内の要素の揃え位置を指定できます。

が、Axisが「Horizontal」か「Vertical」かで指定できる値が変わってきます。

Horizontalの場合

AxisがHorizontalの時に指定できる値はこちら

  • Fill … 縦幅いっぱい
  • Top … 上端揃え
  • Center … 中央揃え
  • Bottom … 下端揃え
  • Baseline(First/Last) … テキストの最初/最後の行のBaselineに合わせる

 

Verticalの場合

Verticalの時に指定できる値がこちら

  • Fill … 横幅いっぱい
  • Leading … 左端揃え
  • Center … 中央揃え
  • Trailing … 右端揃え

 

Distribution … 要素の配置方法

Distributionは要素の配置方法を指定できます。指定できる値は…

  • Fill
  • FillEqually
  • FillProportionally
  • EqualSpacing
  • EqualCentering

UIStackViewのプロパティの中でDistributoionは一番挙動が分かりづらいんですが、プロパティ名を見ると意外と分かりやすいかもしれません。

Fill … StackViewいっぱいに配置

Fillは、StackViewの中がいっぱいになるように中身の要素の幅(Width)や高さ(Height)を取って配置する値です。

挙動としては、AxisがHorizontalなら幅(Width)が、Verticalなら高さ(Height)がStackViewいっぱいになるように自動的に決定されます。

そのため、中身を配置してStackViewの中身が余る場合は要素の幅(高さ)が自動的に伸ばされ、中身が溢れる(はみ出る)場合は要素が自動的に縮められることになるんですよね。

この自動縮小・拡大によるデザイン崩れを防ぐために、StackView内に配置されている要素には、

  • 拡大の優先度を指定する「Hugging Priority」
  • 縮小の優先度を指定する「Compression Resistance Priority」

の2つのプロパティが用意されています。

これらの優先度を部品ごとに変えることで、自動縮小・拡大によるデザイン崩れを防ぐことができるのです。

FillEqually … StackViewいっぱいに「均等に」配置

FillEquallyは、StackViewいっぱいになるように中身の要素を配置しますが、Fillと違い要素の幅(Width)及び高さ(Height)は、各要素設定に関係なく常に等しくなるように配置されます

FillProportionally … StackViewいっぱいに「同じ比率で」配置

FillProportionallyは、StackViewいっぱいになるように中身の要素を配置しますが、FillやFillEquallyと違い、各要素の幅(高さ)の「比率を保ったまま」配置する値です。

多分DistributionのFill系3種の中では一番分かりにくいところだと思うので、使ってみて体感で覚えるしかない気がします(爆)

EqualSpacing … 各要素を「等間隔」空けて配置

EqualSpacingは、各要素を「等間隔」空けて配置する値です。

CSSのFlexboxで言う「space-between」と似たような挙動ですね。

ちなみに要素の幅(高さ)がStackViewより大きい場合は、EqualSpacingを指定しても意味がありません。

EqualCentering … 各要素の「中心からの距離」を等しく配置

EqualCenteringは、各要素の「中心からの距離」を等しく配置する値です。

これは画像を見てもらった方が分かりやすいと思いますが、要素の端から端の間隔を等しく空けるEqualSpacingと違い、EqualCenteringは要素の中心から中心の間隔を等しく空けます。

Spacing … 要素間に空ける間隔

最後のプロパティSpacingは、要素間に空ける間隔を設定することができます。

UIStackViewを使う時のポイントは「入れ子構造にする」

UIStackViewはその特性上「複数ある同じ部品をひとまとめにする」ために使われがちですが、さらに細かい部分もUIStackViewでまとめて「入れ子」にすることで、スッキリ整理されたAuto Layoutを実装することができます。

イメージとしては「ディレクトリ構造」を想像してみてもらうと分かりやすいです。

StackView(フォルダ)ごとに制約(ファイル)をまとめるって感じに整理できるので、ConstrainsのみでAutoLayoutを実装するよりは、レイアウトが把握しやすいですよね。

まとめ

UIStackView、Auto Layoutが苦手な僕としては凄いありがたいアイテムです。

制約(Constrains)は少なくできるし、UI設計自体も直感的にできるようになるという革命的な便利さ。

ConstrainsによるAutoLayoutと、UIStackViewによるAutoLayout、両方極められれば、iOS開発における多画面対応に困ることはなさそうですよね。

AutoLayoutが苦手な方は是非一度使ってみてくださいな!

それでは!

ABOUT ME
mani
mani
21歳のミニマリスト。 余白・インテリアとITが好きでWebやアプリを作ったりしてるエンジニア志望大学生。無駄を省いて「好き」を最大化するミニマリズムを研究中。