Edited at

ScrollViewとStackViewを使った簡単でレイアウト変更に強い実装方法


はじめに

Storyboard上でのScrollViewの実装って結構ややこしいですよね。。。

Autolayoutの設定がわからないとかAutolayoutは設定できたけどスクロールがうまくいかないとか...

初心者の方は特に躓くのではないかと思います。

そんなややこしいScrollViewの実装を簡単にできる方法を紹介したいと思います。

みなさん、ScrollViewをStoryboardで実装するときどのように実装していますか?

ScrollViewのContentViewにUIViewを置いていませんか?

ScrollViewの実装の仕方を調べると大抵の記事はcontentViewにUIViewを置いているのではないかと思います。

UIViewを置くことは間違いではないのですが、このUIViewをStackViewに置き換えることで簡単に実装することができレイアウトの変更に強くなります。


ScrollViewのcontentViewにStackViewを配置する

まずはScrollViewを配置してAutolayoutを設定します。

今回は上下左右0ptで指定します。

スクリーンショット 2019-03-01 18.48.42.png

次にStackViewをScrollViewのcontentViewに配置します。

今回は縦方向のスクロールにするのでStackViewはVerticalのもを使います。

また、StackViewのDistributionをEqual Spacingにしましょう。※ここお忘れなく!

AutolayoutはScrollViewのときと同じように上下左右0ptで設定します。

これだけだとエラーが出るので加えてStackViewの横幅をScrollViewと同じにします。

スクリーンショット_2019-03-01_18_56_36.png

ScrollViewのところまで引っ張って離すとWindowが出てくるのでEqual Widthsを選択します。

これでStackViewの横幅がScrollViewと同じになりました。

ここまではUIViewでの実装と同じです。


UIViewでの実装との違い

ここまでのAutolayoutの設定でまだエラーが出てますね。

では配置したStackViewの中にUIViewを配置してみましょう。

ここでUIViewでの実装との違いを解説します。

contentViewがUIViewの場合、ここまでの手順でエラーは消えません。

contentViewの高さが確定していないためです。

UIViewの場合、中に配置するUIパーツ全ての高さが確定し、全体の高さが決まっていないといけません。

ですが、StackViewを使うと高さのAutolayoutを指定しなくてもエラーにならないのです。

全体のcontent sizeはStackViewが中のUIパーツの高さをみて勝手に計算してくれます。

後は配置したUIViewの中で配置した各UIパーツにAutolayoutを指定していきましょう。

UIView自体に高さを指定しても大丈夫です。

では実際に実行して見てみましょう。

まずは中のUIViewの高さを100にして見てみます。

スクリーンショット 2019-03-01 19.58.10.png

この場合ScrollViewのcontent sizeが100になり、画面内に収まるのでスクロールできません。

次に高さを2000にして見てみましょう。

Storyboard上からはみ出ていますが、一旦気にしなくて大丈夫です。

気になる方はStoryboardのサイズを変えてください!

スクリーンショット 2019-03-01 20.04.08.png

少しわかりづらいかもしれませんが、スクロールができていると思います。

このようにcontent sizeはStackViewが勝手に計算してくれます。


StackViewを使うメリット

ScrollViewのcontent viewにStackViewを使うと以下のメリットがあります。

・全てのレイアウトが完成しなくてもエラーにならない

・content view(StackView)自体の高さのAutolayoutを設定しなくてよい

・レイアウトの修正をするときにAutolayoutの再設定が楽になる ※これが一番うれしいかも


中に配置するViewを切り出してxibで作る

先程配置したUIViewの中で全てのUIパーツを組み立てても良いのですが、デザインや実装の都合上区切りのよいところで分けてそれぞれをxibで作りましょう。

※分けたxibはそれぞれxib内でAutolayoutを設定してください。Storyboard上でデザインを確認したい方はxibのクラスに@IBDesignableを設定しましょう。

xibのレイアウトが完成したらStackViewの中にUIViewを置いてUIViewクラスにxibで作ったクラスを指定します。

このとき配置したUIViewにはAutolayoutを指定しなくて大丈夫です。

ここまでできたら実行してみてください。

どうでしょう?

Storyboard上ではAutolayoutを設定していませんが、ちゃんとxib側で設定したAutolayoutの通りの高さになっているのではないでしょうか?

全てをStoryboard上で組み立てるとレイアウトの修正をするときAutolayoutの修正がとても大変です。

ですが、このようにxibに切り出して実装するとレイアウトの修正する際、切り出したxib内のAutolayoutを修正するだけでよくなります。

以上、StackViewを使ったScrollViewの実装方法でした。


※追記

Xcode11からScrollViewの変更が入ったようで、ScrollViewの中に Content Layout GuideFrame Layout Guide というものが含まれるようになっています。

スクリーンショット_2019-10-08_11_49_06.png

この変更により、この記事のやり方でエラーが出るようになったので、ScrollViewを配置後、ScrollViewを選択して Content Layout Guides のチェックを外してから中にStackViewを配置してください。

スクリーンショット_2019-10-08_11_55_43.png