3

特定のエンティティの単純なツリーで構成されるコア データ モデルがあり、これには 2 つの関係がparentありchildrenます。にバインドされNSTreeControllerたモデルを管理しています。NSOutlineViewNSTreeController

私の問題は、単一のルート オブジェクトが必要なことですが、これはアウトライン ビューに表示されるべきではなく、その子のみがアウトライン ビューのトップ レベルに表示されるべきです。NSTreeControllerInterface Builderのフェッチ述語を に設定するとparent == nil、ルート項目がアウトライン ビューの最上位項目として表示されることを除いて、すべて正常に動作します。

私のエンティティにはisRootItem、ルート項目のみに当てはまる属性 があります。

私のモデルは次のようになります。

Node 1
|
+-Node 2
  |   |
  |   +-Node 5
  |
  Node 3
  |
  Node 4

アウトライン ビューは次のようになります。

アウトライン表示イメージ
(ソース: menumachine.com )

アウトライン ビューの最上位にノード 2、3、および 4 を表示する必要がありますが (ノード 1 は表示されません)、その親は「ノード 1」のままです。ノード 1 の値はYESforisRootItemで、他のすべてのノードの値は ですNO

ツリー コントローラーのフェッチ述語を に設定するとparent.isRootItem == 1、ツリーが正しく表示されますが、新しいアイテムをトップ レベルに追加するとすぐに失敗します。これは、ツリー コントローラーが「見えない」ルート アイテムを親として割り当てないためです。新しいアイテム。

NSTreeControllerこの状況で/のNSOutlineView組み合わせを機能させる方法はありますか?

4

2 に答える 2

2

私がやったのは、NSTreeController をサブクラス化し、オーバーライド-insertObject:atArrangedObjectIndexPath:して、挿入されるオブジェクトがツリーの最上位に挿入されている場合、親をルート オブジェクトに直接設定することです。これは確実に機能するようです。

明らかに、アイテムの移動と複数のアイテムの挿入を処理するには、より多くの作業が必要になりますが、これが最善の方法のようです。

- (void)insertObject:(id)object atArrangedObjectIndexPath:(NSIndexPath *)indexPath
{
    NodeObject* item = (NodeObject*)object;
    //only add the parent if this item is at the top level of the tree in the outline view
    if([indexPath length] == 1)
    {
        //fetch the root item
        NSEntityDescription* entity = [NSEntityDescription entityForName:@"NodeObject" inManagedObjectContext:[self managedObjectContext]];
        NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init]; //I'm using GC so this is not a leak
        [fetchRequest setEntity:entity];
        NSPredicate* predicate = [NSPredicate predicateWithFormat:@"isRootItem == 1"];
        [fetchRequest setPredicate:predicate];

        NSError* error;
        NSArray* managedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];

        if(!managedObjects)
        {
            [NSException raise:@"MyException" format:@"Error occurred during fetch: %@",error];
        }

        NodeObject* rootItem = nil;
        if([managedObjects count])
        {
            rootItem = [managedObjects objectAtIndex:0];
        }
        //set the item's parent to be the root item
        item.parent = rootItem;
    }
    [super insertObject:object atArrangedObjectIndexPath:indexPath];
    //this method just sorts the child objects in the tree so they maintain their order
    [self updateSortOrderOfModelObjects];
}
于 2009-11-06T09:18:53.413 に答える