2009-11-05 2 views
3

두 개의 관계, parentchildren이있는 특정 엔터티의 간단한 트리로 구성된 핵심 데이터 모델이 있습니다. NSOutlineViewNSTreeController에 바인딩 된 NSTreeController 모델을 관리하고 있습니다.NSTreeController, NSOutlineView 및 Core Data를 "보이지 않는"루트 항목과 함께 사용하려면 어떻게해야합니까?

내 문제는 단일 루트 개체가 필요하지만 개요보기에 표시하면 안되며 하위보기 만 개요보기의 최상위에 표시되어야합니다. 인터페이스 작성기에서 의 페치 조건자를 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은 의 값이 isRootItem이고 다른 모든 값은 NO입니다.

트리 컨트롤러의 fetch 조건자를 parent.isRootItem == 1으로 설정하면 트리가 올바르게 표시되지만 최상위 수준에 새 항목을 추가하면 트리 컨트롤러가 "보이지 않는"루트를 지정하지 않으므로 실패합니다 새 항목의 부모 항목입니다.

이 상황에서 NSTreeController/NSOutlineView 조합을 사용할 수있는 방법이 있습니까?

+0

수표없이 'parent.isRootItem'으로 간단히 작성할 수 있습니다. – Abizern

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

NSTreeController의 addChild: 메서드에 바인딩을 시도 했습니까?

NSTreeController를 사용하지 않는 시간 때문입니다.

소스 뷰의 위임 메서드를 구현하면 표시 할 내용을 훨씬 잘 제어 할 수 있습니다. 이 너무 많아서 추가 작업이 아니며 NSTreeController를 원하는 방식으로 작동 시키려고 노력하는 것보다 쉽습니다.

+0

기존 노드의 하위 노드를 만드는 데 적합합니다. 예를 들어, "노드 2"를 선택하고'-addChild :'를 호출하면 자식이 올바르게 생성됩니다. 그러나 내가 할 수없는 일은 노드 2와 동일한 수준의 새로운 노드를 만드는 것입니다. '-add :'를 호출하면 새 노드가 만들어 지지만 그 부모는 내 루트 항목 '노드 1'이 아닌 nil입니다. –

+0

내가 원하는 방식으로 NSTreeController를 작동시킬 수 없다면 NSOutlineView의 데이터 소스/위임 메소드로 되돌릴 것입니다.하지만 NSTreeController는 작업에 너무 가깝기 때문에 먼저 해당 경로를 시도하고 싶습니다. –

+0

다른 답변을 얻는 것이 흥미로울 것입니다. 네가 NSTreeController에 대해 무슨 뜻인지 알지. 가끔은 거의 다 왔어. – Abizern