3

我有一个核心数据模型,它由一个特定实体的简单树组成,它有两个关系,parent并且children. 我有一个NSTreeController管理模型,NSOutlineView绑定到NSTreeController.

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

我的实体有一个属性 ,isRootItem仅适用于根项目。

我的模型如下所示:

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

大纲视图应如下所示:

轮廓视图图像
(来源:menumachine.com

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

如果我将树控制器的 fetch 谓词设置为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 回答
0

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

正是因为这样的时候,我才不使用 NSTreeController。

您可以取消它并实现 Source 视图的委托方法,这将使您更好地控制所显示的内容。这并没有太多额外的工作,并且可能比试图让 NSTreeController 以你想要的方式工作更容易。

于 2009-11-05T06:38:27.440 回答