要約
- Xcode11からIBで
UIScrollViewを使うときはContent Layout GuideとFrame Layout Guideを利用するといいかも - iOS10以下をサポートしたい時は今までとちょっとやり方が変わったから気をつけよう
IB + UIScrollViewは大変
例として、夏目漱石の「我輩は猫である」を表示するだけの画面を作ってみます。
ここではXcode10.2を使用しています。
この画面は、UIScrollViewとContentView(UIView)、2つのUILabelで構成されています。

UIScrollViewをAutolayoutを使って組む場合、以下の制約が必要です。
-
UIScrollView自身の位置 -
UIScrollViewの中身のサイズ -
UIScrollViewの中身の固定された横/縦幅
この制約を満たすために、以下の手順でConstraintを設定しています。
-
UIScrollViewの上下左右をUIViewControllerのViewに合わせる -
ContentViewの上下左右をUIScrollViewに合わせる -
ContentViewの横幅をUIViewControllerのViewに合わせる(Equal Widths) -
ContentViewにオブジェクトを追加して高さを確定させる
慣れれば大したことはないのかもしれませんが、UIScrollViewが持つフレーム領域とコンテンツ領域が混ざって扱われているので、後からStoryboardをみた時どこがどうなってるんだっけ??と混乱すると思います。
ContentLayoutGuideとFrameLayoutGuideの登場
Xcode11から、ScrollViewの中にContent Layout GuideとFrame Layout Guideが追加されました。
名前の通り、Content Layout GuideはUIScrollViewの中身、Frame Layout GuideはUIScrollViewのフレーム領域を示します。
以下の画面を見ると、中身とフレーム領域が明確に分けられていることがわかります。

これらはiOS11から追加された機能でしたが、IB上では扱えず、コード上でUIを組み立てる時しか恩恵を得られませんでした。
Xcode11ではScrollViewの中に追加されており、IBでUIScrollViewを扱う人でも使えるようになりました。
さて、先ほど作った画面をContent Layout GuideとFrame Layout Guideを使うように直すとこうなります。

-
UIScrollViewの上下左右をUIViewControllerのViewに合わせる -
ContentViewの上下左右をContent Layout Guideに合わせる -
ContentViewの横幅をFrame Layout Guideに合わせる(Equal Widths) -
ContentViewにオブジェクトを追加して高さを確定させる
手順としては大きく変わっていないのですが、今までContentViewをUIScrollViewやUIViewControllerのViewに合わせていたところを、それぞれのLayout Guideに合わせることで役割が明確になりました。
iOS10以下もサポートしたいんだけど。。。
残念ながら、contentLayoutGuideとframeLayoutGuideはiOS11からの機能なので、iOS10以下で実行するとクラッシュします。
その場合は従来と同じ方法で実装する流れになりますが、Xcode11では上記の方法の
3 .
ContentViewの横幅をUIViewControllerのViewに合わせる(Equal Widths)
これをやろうとすると、そもそもEqual Widthsの項目がなくなっています(バグ?)
一時的な解決策として、Viewに対してではなくViewのSafeAreaに向けると項目が出てきますので、そっちを使っています。
