前置き
Storyboardで画面を作っている時に困ることとして、UIScrollViewを使用する際、中のコンテンツが一部しか見えない問題があります。
先日同様の悩みをお見かけしました。
自分はStoryboardでContentViewが全画面見えないのが嫌で、ContentViewはxibにしてます。さらにViewControllerにはプログラム側からaddSubviewして、プログラム側で制約をつけてます。
— nori (@1amageek) 2018年7月20日
もっといい方法知りたい。
多くの人は、XibなどContentViewを別ファイル化する、または中のコンテンツが見えない状態でStoryboard上に実装しているのではないかと思っています。
これに対する自分なりの解を書こうと思います。
説明
私のやり方は、StoryboardでContainerViewを用いて作る方法です。
流れとしては下記となります。
1. UIScrollViewControllerを置く
UIScrollViewを用いたい位置とサイズで制約をつけます。
2. UIScrollViewの中のContentViewはContainerViewを置く
UIScrollViewのContentViewとなるViewをContainerView
で配置し、制約をつけます。この時、スクロールさせたい方向にViewを伸ばしてやります。
スクリーンショットでは縦にスクロールさせたいため、ContainerViewのHeightを固定で800px指定しています。
3. ContainerViewに対して各種Viewを置く
ContainerViewには、配置した時点でUIViewControllerが紐づいており、このUIViewControllerの大きさはContainerViewの大きさで表示されるため、これがUIScrollViewのContentViewとなります。
これにより、従来UIScrollViewの中にUIViewを入れてた時とは異なり、ContentViewをUIScrollViewと同一ファイル内で扱え、全容も見たり弄ることができます。
※ContentViewが可変サイズの場合は、別途書く予定です。
補足
副次的なメリットとして
- ContentViewをUIViewControllerとして実装できるため、UIViewとして作るより、LifeCycle途中での処理を記述しやすい
- ContentViewをUIViewControllerとして実装できるため、
touchesEnd
等を使える
デメリットとして
- UIScrollViewが置かれているUIViewController側と分けられるため、ユーザがContentViewで行う操作で、UIScrollViewがあるUIViewController上の何かを操作したい場合、delegate等で伝える仕組みが必要になる