UIPageViewControllerで日めくりカレンダーを作る

iOS5から、UIPageViewControllerというクラスが追加されました。
電子書籍アプリを簡単に作れるようになるのですが、ページめくりを利用して、
日めくりカレンダーを作ってみたいと思います。


プロジェクトの作成

himekuri01.png

Page-Based Applicationで作成します。
プロジェクト名は適当に「himekuri」とかでいいんじゃないでしょうか。

そのまま動かす

まずは、そのまま動かしてみます。

himekuri02.png

1月〜12月とラベルに書いてあるページが出ています。
特に何も書いていませんが、ページめくりが実装されています。

早速いじってみましょう。

StoryBoard

himekuri03.png

上部のLabelを中央あたりに移動させて、文字やLabelの大きさを変えます。

準備

DataViewController.hに1行NSUIntegerを追加しておきます。

@property (strong, nonatomic) IBOutlet UILabel *dataLabel;
@property (strong, nonatomic) id dataObject;
@property (nonatomic) NSUInteger objectIndex;

忘れずにDataViewController.mで@synthesizeしておきます。

@synthesize objectIndex = _objectIndex;

このobjectIndexには、現在のページ番号が入ります。

ModelController.m

ではModelController.mからいじります。

pageDataをbaseDateと名前を変えてNSDateにして、initの中身で今日の日付を取るように変えます。

@interface ModelController()
@property (strong, nonatomic) NSDate *baseDate;
@end

@implementation ModelController

@synthesize baseDate = _baseDate;

- (id)init
{
    self = [super init];
    if (self) {
        // Create the data model.
        _baseDate = [NSDate date];
    }
    return self;
}

indexOfViewControllerでは、先程のobjectIndexを返すように書き換えます。

- (NSUInteger)indexOfViewController:(DataViewController *)viewController
{   
    return viewController.objectIndex;
}

pageControllerBeforeViewControllerではif文を書き換え・・・

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(DataViewController *)viewController];
    if (index == 0) {
        return nil;
    }
    
    index--;
    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}

pageControllerAfterViewControllerではif文ごと消します。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(DataViewController *)viewController];
    
    index++;
    
    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}

viewControllerAtIndexもif文を消し、dataObjectに今日からページ数の分だけ経過させた日付を、objectIndexにはページめくり後のページ番号を入れます。

- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{   
    DataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:@"DataViewController"];
    dataViewController.dataObject = [NSDate dateWithTimeInterval:86400*index sinceDate:self.baseDate];
    dataViewController.objectIndex = index;
    return dataViewController;
}

DataViewController.m

ViewWillAppearで先程のLabelに、日付を表示させるようにします。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[NSLocale currentLocale]];
    
    [dateFormatter setDateFormat:@"d"];
    self.dataLabel.text = [dateFormatter stringFromDate:self.dataObject];
}

ここまでやっておけば一応日めくりっぽくなりますが、横めくりのままも良くないので縦めくりにします。

RootViewController.m

UIPageViewControllerのinit時のUIPageViewControllerNavigationOrientationHorizontalの所を、UIPageViewControllerNavigationOrientationVerticalに書き換えるだけで
縦めくりになります。

    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:nil];

以上で終わりです。すぐですね☆(ゝω・)v

動かしてみる

縦めくりになって、次々を日付が進むようになりました。

himekuri05.png

とりあえずこんな所です。

pageControllerBeforeViewControllerとpageControllerAfterViewControllerはめくった瞬間に呼び出されて、
めくりをやめても実行されるのが分かるまで少し手こずったのは内緒です。

電子書籍アプリだけに使われるのももったいない気がするので、他のアプリでも使われるといいなーと思います。

ソース

taiko19xx/himekuri – GitHub

コメントを残す