2010年6月4日金曜日

NSFetchedResultsController でグルーピング(Section分け)

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
概要
NSFetchedResultsController のインスタンスを作る時に sectionNameKeyPath: へグルーピング条件となるKeyPathを渡すと、簡単に UITableView でグルーピングができる。


例えばこれが
こうなる。


sectionNameKeyPath:
インスタンス作成時のコードはこんな感じ。


NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:coreDataManager.managedObjectContext
sectionNameKeyPath:@"treatedYear" cacheName:@"Root"];



@"treatedYear" を渡している。これがグルーピング条件(今回は「年」)となる。
さて、この treatedYear(年) だが、検索対象のエンティティには実は存在しない。
treatedDate が存在するが、これは NSDate(年月日時分秒)の属性。


treatedDate そのままでは年単位のグルーピング条件に成り得ないので、年を別途用意する必要がある。それが treatedYear。この treatedYear はメソッドとして存在するだけのテンポラリな値で永続化対象にはしていない。




@implementation Record (Extension) ← RecordはNSManagedObjectのサブクラスで、カテゴリでメソッドを追加
- (NSInteger)treatedYear
{
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* dateComponents =
[calendar components:NSYearCalendarUnit
fromDate:self.treatedDate];
return [dateComponents year];
}

NSFetchedResultsController がグルーピングを行う際に、初期化時に指定された sectionNameKeyPath:@"treatedYear" を元にこのメソッドを呼び出す。このメソッドでは treatedDate(NSDat型:年月日時分秒)から年の値だけを取り出して返している。これでグルーピング条件を提供できる。


表示するセクション名
グルーピングするにはさらに UITableViewDataSource の tableView:titleForHeaderInSection: を定義する必要がある。このメソッドが定義されていない場合はグルーピング表示されない。

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
  return [NSString stringWithFormat:@"%@",
[[[fetchedResultsController sections] objectAtIndex:section] name], nil];
}

これで出来上がり。



- - - -
件数が極端に多い場合は「年」をエンティティの属性として追加しておいた方がパフォーマンス的にはいいかもしれない。

0 件のコメント:

コメントを投稿