子ノードには手を出すな(NSTreeController)
Posted 5月 31st, 2010 by hippos
in
このところまたOutlineView+TreeControllerやってます。それでひとつ気づいたことをメモ。
"ツリーコントローラーにストアしているデータをすべてinsertしてもツリー構造にはならない"ということ。読み込んだ子ノードのデータをTreeControllerにinsertすると(親ノードの配下にも表示されますが)親ノードと兄弟のように表示されちゃいますね。ググってみたら、Fetch Predicateに”parent == nil"を指定する(cocoadev:NSTreeController)のが慣例
みたいなんですが知りませでした。データの読み込みを確認しながらようやくわかった次第。要するに親ノードが持っている子ノードの展開はTreeControllerが内部で実行することになっているようでプログラムからは親ノードさえadd/insertしてやれば良いようです。当然バインドの場合でも上記の例のようにPredicateを指定する必要があるようです。(Appleの公式ドキュメントとしてどこかに書かれているのかな?)
NSManagedObjectContext *moc = [self managedObjectContext];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
NSArray* sortDesc = [NSArray arrayWithObject:
[[[NSSortDescriptor alloc] initWithKey:@"orderNo" ascending:YES] autorelease]];
[fetch setEntity:
[NSEntityDescription entityForName:@"ChildNodeEntity" inManagedObjectContext:moc]];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"isLeaf == 0"]];
[fetch setSortDescriptors:[self sortDesc]];
NSError *err = nil;
NSArray *results = [moc executeFetchRequest:fetch error:&err];
if ((err) || (results == nil))
{
[NSApp presentError:err];
return;
}
NSUInteger index = 0;
for (ChildNodeEntity *node in results)
{
[treeController insertObject:node atArrangedObjectIndexPath:
[NSIndexPath indexPathWithIndex:index]];
index = index + 1;
}まあ、実際にやりたかったのはノードの表示順を一定に保つことでCocoaDevのリンクnstreecontroller-and-core-data-sortedにもあったようにノードの中になんらかの方法で順序を示す数値を仕込んでおけばOK。子ノードの展開はTreeControllerお任せになるのでSortDescriptorをバインドする必要もあります。ロード時に特別の処理がなければ僕のコードのようにガリガリコードを書くのは不作法で、やっぱりバインドしたほうがスマートですね。
この記事のトラックバックURL:
http://hippos-lab.com/blog/trackback/371






Comments