[iOS 9] UIStackViewを知らない人向けの基礎知識
はじめに
この内容は昨年6月に北海道で開催した『Developers.IO Meetup 11 in Sapporo』でUIStackViewについて発表した内容を、(すごく今更感はありますが)再度Blogにまとめたものです。
元のスライドはiOS9が発表された直後に書いたので内容が薄いUIStackViewを知らない人向けの内容になってます。
UIStackViewとは
UIStackViewは、縦または横に並べる用のレイアウトになります。AndroidでいうところのLinearLayoutのようなイメージです。
UIStackViewが登場する前
UIStackViewが登場する前には均等に横に並べるようなレイアウトを作るには、間にSpacerのUIViewを入れて制約たくさんつける必要があり、ちょっと面倒でした。
※ SpacerViewを配置する方法は公式ドキュメントに記載されていた方法です。
(参考:Auto Layout ガイド - ビューを等間隔で並べる (P.31) )
UIStackViewを使用して配置する
UIStackViewを使用して等間隔に配置すると、ボタンなどのsubview自体の制約が不要になります。 よって制約自体が少なくなって、作成するのが楽になります。 下記画像では、UIStackViewは画像下のボタン部分に使用してます。
UIStackViewの使い方
StoryboardでStackViewを配置する方法
サンプルとして↑に載せている、きりんのレイアウトを作るまでの手順です。
1.Image Viewを配置します
2.Image Viewに制約をつけます
ここでは、上左右を0、高さを230にしてます。またわかりやすいように画像もセットしておきました。
3.Stack Viewを配置します
今回は横に並べるため Horizontal Stack View を使用しました。
4.Stack View自体に制約をつけます
StackView自体の位置やサイズの調整です。上:ImageViewから0、左右:0、高さを60にしました。
5.Stack Viewのプロパティを修正します
今回は等間隔にしたいのでDistributionをFill Equallyにしました。
尚、stack view の配置は以下のプロパティに基づきます。
プロパティ名 | 説明 |
---|---|
axis | レイアウトの軸(垂直or水平) |
distribution | レイアウトの分布 |
alignment | 垂直のレイアウト |
spacing | View間の最小間隔 |
6.ボタンを配置します
StackView内にボタンを配置します。画像も一緒にセットしておきます。
7.Text Viewを配置して制約をつけます
上記の手順でレイアウト配置は完成です
Stack View Tips
縦と横で並べ方を変更する
端末の向きを変えた時にそのままだと並べ方は変わりません。下記図では、端末を横にしても縦並びのままです。
それを、端末を横にした時は横並びにするには、StackViewをOutlet接続しコード上でaxisを変更します。
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() dispatch_async(dispatch_get_main_queue()) { if self.view.frame.height > self.view.frame.width { // 縦方向に並べる self.mainStackView.axis = UILayoutConstraintAxis.Vertical } else { // 横方向に並べる self.mainStackView.axis = UILayoutConstraintAxis.Horizontal } } }
上記処理を入れると端末が縦の時は縦並びに、横にした時は横並びになります。
SubViewsの数を変化させる
下記イメージのようにボタンを押した時にSubViewの数を変更させるには、hiddenを切り替えるだけで自動的に最適なレイアウトになります。
@IBAction func didTapPlusButton(sender: UIButton) { for subview in self.mainStackView.arrangedSubviews { if subview.hidden { subview.hidden = false break } } } @IBAction func didTapMinusButton(sender: UIButton) { for subview in self.mainStackView.arrangedSubviews { if !subview.hidden { subview.hidden = true break } } }
また、上記は表示/非表示で切替えてましたが、subViewを生成して増やしても自動的に最適なレイアウトになります。
//subviewを追加する(最後に追加) self.stackView.addArrangedSubview( subview )
//subviewを追加する(任意の位置に追加/↓は先頭) self.stackView.insertArrangedSubview(subview, 0)
//subviewを削除する self.stackView.removeArrangedSubview( subview )
たくさん追加すると下記イメージのように増えます。
Stack View の中に Stack View を入れる
下記イメージのようにStackViewは入れ子にすることが出来ます。
さいごに
並び方の向きをプロパティ1つで切替えられたり、hiddenでレイアウトを自動的に切替えるのが便利です。また、AndroidのView.GONEみたいな使い方も出来ます。個人的には等間隔に並べたい時に凄く手軽になったと思いました。