UICollectionViewを使用しての横スクロールを実装するUIは多々あると思いますが、検索して出てくる情報ではかなり微妙な動作が多く、自分の決定版として作成方法をまとめます。
今回の作成はAutoLayoutは使用しておりません。
完成イメージ (画像は今回作成段階で参考にさせていただいたeuraka様のブログより転載させていただいてます)
参考記事のように作成する
まず、はじめにeureka様がまとめてくださっている記事のように実装してみました。
タイムラインの実装に欠かせない!UICollectionViewで作るFacebook風レイアウト
作成してみると確かに綺麗にTimeline風の横スクロールが実装されています。
しかし、作成の過程上、左右にすき間が発生してしまい、スクロール判定がきかない箇所ができてしまいます。
表示枠のでかいcellの作るのでしたらあまり気にならない部分ではありますが、どうしても端からスクロールするときにひっかかってしまい良い動作とは言えません。
両サイドをタップ可能にする
そこで、この問題を解決するために、UICollectionViewの前に1枚UIViewをはさみ両サイドの部分をタップできるようにします。
今回作成したデモアプリをGithubの方にあげていますので、ぜひ確認してください。
https://github.com/Econa77/PagingCollectionView
変更点は以下の部分です。
・CollectionViewを直に使用せず、UIViewをはさむ
・UIViewのhitTestを使用して本来CollectionViewが無い部分の動作をcollectionView動作させる
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
if !CGRectContainsPoint(self.collectionView.frame, point) {
return self.collectionView
}
return super.hitTest(point, withEvent: event)
}
内部のcellのサイズは現状決め打ちとなっていますので、使用する際は自由に変更してください。
基本的に重要なポイントはeureka様のブログの方に綺麗にまとまっています。
別の方法
実装の方法を調べている中でよく上がっているのは、Layoutファイル内のスクロール動作を制御してページングを行っている方法です。
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {}
http://stackoverflow.com/questions/13492037/targetcontentoffsetforproposedcontentoffsetwithscrollingvelocity-without-subcla
http://shingt.com/blog/2014/08/31/cell-paging-for-uicollectionview/
この方法の場合、CollectionViewの余計なpaddingなど気にせずに横スクロールは実装できますが、綺麗なページング動作を行ってくれません。
具体的には、勢いを付けて横スクロールをすると、1ページ飛ばしてスクロールしてしまいます。
また、UIcollectionViewにヘッダーやフッターを追加した際のページング動作の定義がされていないため、ヘッダーとフッターページの時にページング動作を行うことができません。
こちらの方法は実装は簡単ですが、動作に癖がありますので、実装する際は使用用途を考えた上で実装してください。