2009-11-05 34 views
3

我有一个核心数据模型,它由一个特定实体的简单树组成,它有两个关系,parentchildren。我有一个NSTreeController管理模型,NSOutlineView绑定到NSTreeController如何将NSTreeController,NSOutlineView和Core Data用于“不可见”根项目?

我的问题是我需要一个根对象,但这不应该显示在大纲视图中,只有它的子项应显示在大纲视图的顶层。如果我将Interface Builder中的NSTreeController的获取谓词设置为parent == nil,则一切正常,除了根项目作为大纲视图中的顶级项目可见。

我的实体有一个属性isRootItem,这对于根项目来说只适用。

我的模型看起来是这样的:

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

大纲视图应该是这样的:

Outline View Image http://menumachine.com/quickies/nodes.png

我需要的顶级显示节点2,3和4大纲视图(节点1不应该是可见的),但仍然有他们的父母是“节点1”。节点1的值为YESisRootItem),其他所有节点的值为NO

如果我将树控制器的获取谓词设置为parent.isRootItem == 1,这会正确显示树,但只要向最高级别添加一个新项目,就会失败,因为树控制器未分配“不可见”根目录项目作为新项目的父项目。

有没有办法让NSTreeController/NSOutlineView组合在这种情况下工作?

+0

您可以在没有检查的情况下简单地将谓词写为'parent.isRootItem'。 – Abizern 2009-11-05 07:01:59

+0

谢谢,你是对的。 – 2009-11-05 07:20:45

回答

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]; 
} 
0

你试过绑定到NSTreeController的addChild:方法吗?

这是因为这样的时代,我不使用NSTreeController。

你可以放弃它,并实现源代码视图的委托方法,这将使你更好地控制你显示的内容。这不是太多额外的工作,并可能比打你试图让NSTreeController工作你想要它如何更容易。

+0

这适用于创建现有节点的子节点。例如,如果我选择“节点2”并调用“-addChild:”,那么将会正确创建一个孩子。但是,我不能做的是在与节点2相同的级别创建新节点。如果我调用'-add:',则会创建一个新节点,但其父节点为零,而不是我的根节点“节点1”。 – 2009-11-05 06:45:32

+0

如果我无法按我需要的方式获得NSTreeController,那么我一定会恢复到NSOutlineView的数据源/委托方法,但是NSTreeController非常接近工作,我想先尝试该路径。 – 2009-11-05 07:02:39

+0

看到还有其他答案会很有趣。我知道你对NSTreeController的意义 - 有时候感觉就像是在那里...... – Abizern 2009-11-05 07:13:01

相关问题