iOSには標準でページめくり用のコンポーネントが用意されています。iPhoneのホーム画面のようにページコントロールがあって、左右スワイプでページめくりができるアレです。

この機能を実装するためにはUIPageViewControllerなどを使います。ところが実装がめちゃくちゃ面倒くさいんですよ。以前作ったときはいろいろ調べてみつけた英語の記事を参考に実装したんだけど、もう全然覚えていません。リンクだけは残してあったりして。

How To Create UIPageViewController in Storyboard | iOS ProgrammingHow To Create UIPageViewController in Storyboard | iOS Programming

で、嫌気がさしてCocoaControlsを漁っていたらページコントロール系のPodを見つけたので試してみました。実装方法は標準のUIPageViewControllerに近いところもあるのですが、わりといい感じかもしれないのでレポります。

ICViewPager

monsieurje/ICViewPager

サンプルプロジェクトをSingle View Applicationとして作成しICViewPagerを使ってみます。最初にSingle View Applicationを作っておきます。

インストール

CocoaPodsでインストールし、xcworkspaceを開きます。

1$ vi Podfile
2pod 'ICViewPager'
3
4$ pod install

Controllerクラスを追加

ページ全体を管理するPageControllerクラスと、各ページのViewを担当するContentViewControllerを用意します。

PageController

PageControllerはICViewPagerのViewPagerControllerのサブクラスにし、デリゲートとデータソースを実装するようにプロトコルを継承しておきます。

1#import "ViewPagerController.h"
2
3@interface PageController : ViewPagerController<ViewPagerDataSource,ViewPagerDelegate]]>
4
5@end

ContentViewController

こいつは普通のViewControllerで良いです。

storyboardでやること

最初からあるViewControllerのカスタムクラスをPageControllerに、新しく追加したUIViewControllerのカスタムクラスをContentViewControllerにします。

また、後でコードから呼び出すためにContentViewControllerのほうはStoryboard IDにも同じ名前を付けておきます。

ページめくりを確認するために申し訳程度にラベルを置いておきました。このラベルをソースから変更できるようにIBOutletとしてContentViewControllerと紐付けておきます。また、ラベルに描画するテキストを一時的に置いておくためのNSStringのプロパティも1つ用意しておきます。

1#import <UIKit/UIKit.h>
2
3@interface ContentViewController : UIViewController
4
5@property (weak, nonatomic) IBOutlet UILabel *label;
6@property NSString* labelText;
7
8@end

あとはコードで

データソース、デリゲートに自分自身を設定します。必須なのはデータソースのメソッドのみですのでそれを実装します。

 1// PageController.m
 2- (void)viewDidLoad
 3{
 4    [super viewDidLoad];
 5    // Do any additional setup after loading the view.
 6
 7    self.dataSource = self;
 8    self.delegate = self;
 9
10}
11
12
13- (NSUInteger)numberOfTabsForViewPager:(ViewPagerController *)viewPager
14{
15    // タブの数
16    return 5;
17}
18
19- (UIView *)viewPager:(ViewPagerController *)viewPager viewForTabAtIndex:(NSUInteger)index
20{
21    // タブに表示するView、今回はUILabelを使用
22    UILabel* label = [UILabel new];
23    label.text = [NSString stringWithFormat:@"Tab #%i", index];
24    [label sizeToFit];
25    return label;
26}
27
28- (UIViewController *)viewPager:(ViewPagerController *)viewPager contentViewControllerForTabAtIndex:(NSUInteger)index
29{
30    // タブ番号に対応するUIViewControllerを返す
31    ContentViewController* contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ContentViewController"];
32    contentViewController.labelText = [NSString stringWithFormat:@"Tab #%i", index];
33    return contentViewController;
34
35}

最後に ContentViewControllerviewDidLoadでラベルのテキストを更新してあげれば完了です。

1- (void)viewDidLoad
2{
3    [super viewDidLoad];
4// Do any additional setup after loading the view.
5
6    self.label.text = self.labelText;
7
8}

最初に紹介したアニメーション画像が完成したサンプルにあたります。

ソースコードはここ→pi-chan/icviewpager-sample

その他にできること

  • タブを画面下に
  • 選択中のタブの色
  • タブの背景色
  • タブの大きさ

などなど、いくつかカスタマイズも可能です。