TapkuLibraryでカレンダーを表示

iPhoneでカレンダーを使いたいケースは結構あるのではないかと思います。

カレンダーを使えるようにするライブラリーはいろいろあるようですが、TapkuLibraryが評判が良さそうなので、設定手順などをメモ。
自分なりに試行錯誤した箇所もあります。
間違いや、もっと効率のいい方法などありましたらご指摘いただけたらと思います。

プロジェクトに設定
まずはライブラリーをダウンロードします。
GitHub - devinross/tapkulibrary: tap + haiku = tapku, a well crafted open source iOS framework

Frameworksで「Add files to XXX」を選択

TapkuLibrary.xcodeprojを追加します。

同様に、TapkuLibrary.bundleも追加します。


次に、プロジェクトの「Target Dependencies」にTapkuLibraryを追加

「Link Binary With Libraries」にlibTapkuLibrary.a、MapKit.framework、QuartzCore.frameworkを追加します。


TapkuLibraryのsrcディレクトリをまるごとプロジェクトの直下にコピーします。

「Build Settings」の「Header Search Paths」にsrcディレクトリを指定

実際はこんな感じになります。

「Other Linker Flags」に"-all_load ObjC"を指定します。

以上で設定は完了です。

カレンダーの表示

カレンダービューを表示させたいViewControllerで下記のように指定します。

XXXViewController.h

#import <TapkuLibrary/TapkuLibrary.h>

@interface TapkuSampleViewController : UIViewController <TKCalendarMonthViewDelegate,TKCalendarMonthViewDataSource>
{
	TKCalendarMonthView *calendarView;
}

@property (nonatomic,retain) TKCalendarMonthView *calendarView;

XXXViewController.m

@synthesize calendarView;

- (void)viewDidLoad
{
    [super viewDidLoad];
     // Do any additional setup after loading the view, typically from a nib.

     // カレンダービューを作成
     calendarView = [[TKCalendarMonthView alloc]init ];
     calendarView.delegate = self;
     calendarView.dataSource = self;
     [self.view addSubview:calendarView];

     [calendarView reload];

}

-(void)dealloc
{
     if(calendarView != nil)
     {
          [calendarView release];
     }

     [super dealloc];
}

とりあえずこれで動くと思います。


年月と曜日の日本語化
TapkuLibraryのソースを修正して日本語化します。(もっといい方法があったら教えて下さい。<(_ _)>)

XcodeからTapkuLibrary.xcodeproj/TapkuLibrary/UI/Calendar/Month/TKCalendarMonthView.mを開き、修正します。

TKCalendarMonthView.m

// 日本語で年月を表示するメソッドを追加
-(NSString*)getMonthYearString:(NSDate*) date
{
     NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
     [dateFormat setDateFormat:@"yyyy年 M月"];
     return [dateFormat stringFromDate:date];
}

...
// initWithSundayAsFirstメソッド内の箇所を修正
// 年月表示部分 660行目付近
self.monthYear.text = [self getMonthYearString:date];// [NSString stringWithFormat:@"%@ %@",[date monthString],[date yearString]];

...

// 曜日表示部分 685行目付近
//NSTimeZone *tz = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSString *sun = [NSString stringWithString:@"日"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 6;
NSString *mon = [NSString stringWithString:@"月"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 7;
NSString *tue = [NSString stringWithString:@"火"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 8;
NSString *wed = [NSString stringWithString:@"水"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 9;
NSString *thu = [NSString stringWithString:@"木"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 10;
NSString *fri = [NSString stringWithString:@"金"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

sund.day = 11;
NSString *sat = [NSString stringWithString:@"土"];//[dateFormat stringFromDate:[NSDate dateFromDateInformation:sund timeZone:tz]];

...

// changeMonthAnimationメソッド内の箇所を修正
// 815行目付近
monthYear.text = [self getMonthYearString:localNextMonth];//[NSString stringWithFormat:@"%@ %@",[localNextMonth monthString],[localNextMonth yearString]];

これで日本語表示になると思います。


指定の日付にマーク(・)をつける
Delegateメソッドを実装します。

// カレンダーの日にマークをつける
-(NSArray *)calendarMonthView:(TKCalendarMonthView *)monthView marksFromDate:(NSDate *)startDate toDate:(NSDate *)lastDate
{
     NSMutableArray *marks = [NSMutableArray array];
     // サンプルでマークを付ける日付
     NSArray *markingDateArray = [NSArray arrayWithObjects:@"2012/06/15",@"2012/06/29",@"2012/07/02",
                                                            @"2012/07/03",@"2012/08/15", nil];

     NSDateFormatter *formatter = [[[NSDateFormatter alloc]init]autorelease];
     [formatter setDateFormat:@"yyyy/MM/dd"];

     NSDate *d = startDate;

     while(YES)
     {
          if([d compare:lastDate] == NSOrderedDescending)
          {
               break;
          }

          // 日付をyyyy/MM/ddに
          NSString *dString = [formatter stringFromDate:d];

          if([markingDateArray containsObject:dString])
          {
               [marks addObject:[NSNumber numberWithBool:YES]];
          }
          else {
               [marks addObject:[NSNumber numberWithBool:NO]];
          }

          TKDateInformation di = [d dateInformation];
          di.day++;
          d = [NSDate dateFromDateInformation:di];
     }

     return marks;
}

指定した日付にマークが付きます。


その他
月によっては、5週表示の場合と6週表示の場合があり、これによってカレンダービューの高さが変わります。
カレンダービューのすぐ下に別のビューを配置している場合、重なってしまうことがあります。

表示月が変わった時に呼び出されるDelegateメソッドを実装し、ビューの位置を調整します。

-(void)calendarMonthView:(TKCalendarMonthView *)monthView monthDidChange:(NSDate *)month animated:(BOOL)animated
{
     // UITableViewの位置を変える
     CGRect tableViewRect = CGRectMake(0, monthView.frame.size.height, 
            self.view.frame.size.width, 
            self.view.frame.size.height - monthView.frame.size.height);
     tableView.frame = tableViewRect;
}

未解決事項(調査中)

  • iOS4.3シミュレーターで動かそうとすると、エラーが発生する


参考にさせていただいたサイト
TapkuLibraryをXCode4に組み込む – sabitori works
TapkuLibraryのカレンダーを使ってみた - ちくわプログラマにっき

2012/07/23 追記
・TapkuLibraryのsrcディレクトリに関する設定を追記しました