##はじめに
StoryboardでのUIScrollViewの設定を、AutoLayoutだけでやろうとすると、かなり混乱します。
色々やっているうちに理解出来てきたのでまとめます。
##UIScrollViewのパラメータについて
UIScrollViewには、表示するContentを管理するパラメータとして、
- contentOffset
- contentInset
- contentSize
の3つがあります。
contentOffsetは、どれぐらいスクロールしているか。
contentInsetは、余分にどれだけスクロールできるか。
contentSizeは、スクロールする中身のサイズ。
をそれぞれ表しています。
AutoLayoutによって、中身に応じたcontentSizeを自動的に決定することが出来ます。
##仕組み
この記事では、UIScrollViewの中にある、contentSizeの大きさを持ったスクロールするViewのことを、contentViewと呼ぶことにします。
混乱の元なのが、
「UIScrollViewの中に置いたViewの制約は、UIScrollViewからではなく、contentViewからの制約になり、それを元にcontentSizeが決定される」
ということです。
きったない絵で申し訳ないですが、以下をご覧ください。
このような制約をつけた場合、contentSizeは、600x500になる、ということです。
つまり、見かけ上UIScrollViewに対してつけている制約は、contentViewに対してつけていることになっています。
見た目に惑わされず、制約はUIScrollViewと同じサイズのViewに対してつけているのではなく、contentViewに対してつけている、ということを意識すると混乱しなくなると思います。
##実践
とはいえ、このような仕組みを理解したとしても、常にcontentSizeを意識して制約をつけていくことはとても難しいです。
なので個人的には、UIScrollView直下にはUIViewを1つだけ配置して上下左右に0ptの制約をつける、という方法をオススメします。
そうすれば、あとはそのUIViewの高さと幅を決定すれば良い、という状態にすることが出来ます。
Xcodeではこんな感じ
この状態から、UIViewに対して幅や高さの制約を追加したりサブビューを追加したりすると理解が深まると思います。
また、例えば横にのみスクロールしたい場合は、UIViewとUIScrollViewの間にEquals Heightsの制約をつければ良いです。
##ちなみに
contentOffsetやcontentInsetはAutoLayoutではどうにもなりません。
contentInsetはUser Defined Runtime Attributesで指定できます。
こんなのもありましたが、僕のXcodeにはありませんでした。
contentOffsetは、AutoLayout適用後のviewDidLayoutで設定すると良いと思います。