(iOS6からはUICollectionViewを使ったほうがいいとは思いますが、ATPagingViewの説明としてこの記事は残しておきます)
UIScrollViewで写真閲覧スクロール表示を実装するとき、再利用や先読みが必要であればATPagingView(https://github.com/andreyvit/SoloComponents-iOS) クラスの設計が参考になる。
また、ATPagingViewではスクロールのために必要になるUIScrollViewDelegateをページングのみ特化するプロトコルを定義することで処理をわかりやすくもしている。
ATPagingViewDelegateに定義されているプロトコルは次の通り
@protocol ATPagingViewDelegate <NSObject>
@required
//ページ数を返すようにする。UITableViewのtableView:numberOfRowsInSection:と同じようなメソッド
- (NSInteger)numberOfPagesInPagingView:(ATPagingView *)pagingView;
//必要になったページviewを生成。UITableViewのtableView:cellForRowAtIndexPath:と同じようなメソッド
- (UIView *)viewForPageInPagingView:(ATPagingView *)pagingView atIndex:(NSInteger)index;
@optional
//optionalなメソッドはスクロールのために必要になるUIScrollViewDelegateを直接使う必要がないようにしている
//ページ番号が切り替わった時(表示は前のページの状態)
- (void)currentPageDidChangeInPagingView:(ATPagingView *)pagingView;
//ページ番号が切り替わった時2度呼ばれる(必要性は不明)
- (void)pagesDidChangeInPagingView:(ATPagingView *)pagingView;
//スクロール開始時に呼ばれる
- (void)pagingViewWillBeginMoving:(ATPagingView *)pagingView;
//スクロールが終了した際に呼ばれる
- (void)pagingViewDidEndMoving:(ATPagingView *)pagingView;
@end
ATPagingViewでのページの先読み
ページの先読みはATPagingViewのpagesToPreloadプロパティに指定することで先読みを行うことが出来る。
この先読みは表示されているページの前後の数を指定することになり、2を指定した場合は*2の合計4ページの先読みとなる。
ATPagingViewでのビューの生成と再利用
requiredな2つのメソッドの1つ、numberOfPagesInPagingView:で指定するのは全てのページ数。これによりUIScrollViewのcontentsSizeが決定しスクロールできる範囲が決まる。
次に先述したviewForPageInPagingView:atIndex:メソッドにより表示しようとするページのViewを生成する。このメソッドを実装する場合、dequeueReusablePageメソッドにより再利用queueからUIViewを取り出す
- (UIView *)viewForPageInPagingView:(ATPagingView *)pagingView atIndex:(NSInteger)index
{
UIView *view = (UIView *)[pagingView dequeueReusablePage];
if (view == nil) {
//再利用できなければ生成する
view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
/*…ここでUIImageViewなどをセットする...*/
return view;
}
ATPagingViewでのページ切り替え
UIScrollViewDelegateではドラッグし始めたかどうかや減速しているかどうかのフラグがあるが、ページングにはそういった情報は必要がない場合が多いため機能として最低限のものを用意し処理をわかりやすくしている。
スクロール開始時に呼ばれるpagingViewWillBeginMoving:メソッドはスクロール中にツールバーやナビゲーションバーのボタンを非活性にしたい場合などに使え、pagingViewDidEndMoving:は非活性化したボタンの活性化や各ページのスケールリセット等を行うのに役に立つ。