LoginSignup
143
127

More than 5 years have passed since last update.

UIScrollViewにおけるAutoLayoutについてまとめる

Last updated at Posted at 2015-08-07

はじめに

StoryboardでのUIScrollViewの設定を、AutoLayoutだけでやろうとすると、かなり混乱します。
色々やっているうちに理解出来てきたのでまとめます。

UIScrollViewのパラメータについて

UIScrollViewには、表示するContentを管理するパラメータとして、

  • contentOffset
  • contentInset
  • contentSize

の3つがあります。
contentOffsetは、どれぐらいスクロールしているか。
contentInsetは、余分にどれだけスクロールできるか。
contentSizeは、スクロールする中身のサイズ。
をそれぞれ表しています。

AutoLayoutによって、中身に応じたcontentSizeを自動的に決定することが出来ます。

仕組み

この記事では、UIScrollViewの中にある、contentSizeの大きさを持ったスクロールするViewのことを、contentViewと呼ぶことにします。

混乱の元なのが、
「UIScrollViewの中に置いたViewの制約は、UIScrollViewからではなく、contentViewからの制約になり、それを元にcontentSizeが決定される」
ということです。

きったない絵で申し訳ないですが、以下をご覧ください。

d.png

このような制約をつけた場合、contentSizeは、600x500になる、ということです。
つまり、見かけ上UIScrollViewに対してつけている制約は、contentViewに対してつけていることになっています。

見た目に惑わされず、制約はUIScrollViewと同じサイズのViewに対してつけているのではなく、contentViewに対してつけている、ということを意識すると混乱しなくなると思います。

実践

とはいえ、このような仕組みを理解したとしても、常にcontentSizeを意識して制約をつけていくことはとても難しいです。
なので個人的には、UIScrollView直下にはUIViewを1つだけ配置して上下左右に0ptの制約をつける、という方法をオススメします。
そうすれば、あとはそのUIViewの高さと幅を決定すれば良い、という状態にすることが出来ます。

Xcodeではこんな感じ

スクリーンショット 2017-07-26 9.51.15.png

この状態から、UIViewに対して幅や高さの制約を追加したりサブビューを追加したりすると理解が深まると思います。

また、例えば横にのみスクロールしたい場合は、UIViewとUIScrollViewの間にEquals Heightsの制約をつければ良いです。

ちなみに

contentOffsetやcontentInsetはAutoLayoutではどうにもなりません。
contentInsetはUser Defined Runtime Attributesで指定できます。
こんなのもありましたが、僕のXcodeにはありませんでした。
contentOffsetは、AutoLayout適用後のviewDidLayoutで設定すると良いと思います。

参考

リファレンス
Qiita記事

143
127
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
143
127