我有一个Core Data模型,它由一个特定实体的简单树组成,它有两个关系parent
和children
。我有NSTreeController
管理模型,NSOutlineView
绑定到NSTreeController
。
我的问题是我需要一个根对象,但是这不应该显示在大纲视图中,只有它的子项应该显示在大纲视图的顶层。如果我将Interface Builder中NSTreeController
的fetch谓词设置为parent == nil
,那么一切正常,除了根项目在大纲视图中作为顶级项目可见。
我的实体有一个属性isRootItem
,仅对根项有效。
我的模型看起来像这样:
Node 1
|
+-Node 2
| |
| +-Node 5
|
Node 3
|
Node 4
大纲视图应如下所示:
(来源:menumachine.com)
我需要在大纲视图的顶层显示节点2,3和4(节点1不应该是可见的),但是它们的父节点仍然是“节点1”。节点1的YES
值为isRootItem
,其他所有值均为NO
。
如果我将树控制器的fetch谓词设置为parent.isRootItem == 1
,则会正确显示树,但是只要我将新项添加到顶层,它就会失败,因为树控制器没有分配“不可见的“根项目作为新项目的父项。
有没有办法让NSTreeController
/ NSOutlineView
组合在这种情况下工作?
答案 0 :(得分: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];
}
答案 1 :(得分:0)
您是否尝试过绑定到NSTreeController的addChild:
方法?
因为有这样的时间我不使用NSTreeController。
您可以取消它并实现Source视图的委托方法,这将使您更好地控制您显示的内容。它不是太多额外的工作,可能比敲打你试图让NSTreeController以你想要的方式工作更容易。