要約
- 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に向けると項目が出てきますので、そっちを使っています。