Skip navigation.
 
mlRe: NSTreeController problems
FROM : Jonathan Dann
DATE : Sun May 18 22:33:41 2008

On 18 May 2008, at 20:57, Charles Srstka wrote:

> Lately, I've been trying to update my stodgy old ways and try to 
> incorporate some of the new technologies Cocoa has picked up over 
> the years when starting new projects (my main app has had to be 
> compatible with older OS X versions, so I haven't had much 
> opportunity to jump into the world of bindings prior to now). One of 
> these is NSTreeController. Unfortunately, I'm having a bit of 
> trouble using figuring out how to do what I want with it.
>
> 1. The order of the objects in my (non-Core Data) data model is 
> sometimes important, so rather than using the tree controller to add 
> objects, I have been adding them manually by calling the appropriate 
> -insertObject:in<key>atIndex: methods. Okay, that works pretty well, 
> and the objects show up in the NSOutlineView. However, I'd like to 
> select the objects after I insert them. Now, I know where these 
> objects are in the model, but since the order of the objects in the 
> outline view might be different due to the user clicking on one 
> column header or another to sort, and since the index paths sent to 
> the tree controller's -setSelectedIndexPaths: method seem to be 
> based on the interface, not the model, I don't know exactly where 
> these objects are in order to select them. NSTreeController appears 
> to have no -indexPathForObject: method or anything similar - does 
> anyone know a way around this?
>
>     1a. At first I thought that since I am making a sibling to the 
> currently selected object, I could just get the parent's index path 
> via [[treeController selectionIndexPath] 
> indexPathByRemovingLastIndex], then get the node at that index path 
> and iterate through its -childNodes until I find the one whose -
> representedObject is the correct model object, but there doesn't 
> seem to be any way to get NSTreeController to give the node (or the 
> model object, for that matter) for an index path. Does anyone else 
> find this a little bizarre


To have an indexPathForObject method you need this:


- (NSArray *)rootNodes;
{
   return [[self arrangedObjects] childNodes];
}

// this is a depth-first search
- (NSArray *)flattenedNodes;
{
   NSMutableArray *mutableArray = [NSMutableArray array];
   for (NSTreeNode *node in [self rootNodes]) {
       [mutableArray addObject:node];
       if (![[node valueForKey:[self leafKeyPath]] boolValue])
           [mutableArray addObjectsFromArray:[node valueForKey:@"descendants"]];
   }
   return [[mutableArray copy] autorelease];    
}

- (NSTreeNode *)treeNodeForObject:(id)object;
{    
   NSTreeNode *treeNode = nil;
   for (NSTreeNode *node in [self flattenedNodes]) {
       if ([node representedObject] == object) {
           treeNode = node;
           break;
       }
   }
   return treeNode;
}

- (NSIndexPath *)indexPathToObject:(id)object;
{
   return [[self treeNodeForObject:object] indexPath];
}

They're all separate methods as I have quite a few extensions on 
NSTreeController!

>
> 2. Okay, so I've got my objects displaying in an NSOutlineView, and 
> now I'd like to add a search feature. Rather than eliminating the 
> options that don't match, what I want to do is find the object, 
> expand all its ancestors in the outline view so it's visible, and 
> select it. Finding the model object is easy, and doing the rest 
> *would* be easy enough if I weren't using NSTreeController - just 
> climb the family tree, use -rowForItem: for each, expand it, and 
> then use -rowForItem: to get the object and select it. Of course, 
> with NSTreeController we have all these NSTreeNode objects instead 
> of the actual objects themselves in the outline view, so -
> rowForItem: won't work. Is there any way to find the rows for the 
> various nodes in the family tree of an object without resorting to 
> just iterating through every row in the outline view? Any way to get 
> the tree node for a given model object?


Now you have a treeNode for object you can as the NSOutlineView to 
expand that item (the NSTreeNode) using -expandItem:

Ive recently written two posts on NSTreeController, the first is non-
Core Data the second is with core data but the sample project has a 
load of extensions that let you do what you want to do. They're at

http://jonathandann.wordpress.com/2008/04/06/using-nstreecontroller/

and

http://jonathandann.wordpress.com/2008/05/13/nstreecontroller-and-core-data-sorted/

Hope this helps

Jon

Related mailsAuthorDate
mlNSTreeController problems Charles Srstka May 18, 21:57
mlRe: NSTreeController problems Jonathan Dann May 18, 22:33
mlRe: NSTreeController problems Charles Srstka May 18, 22:57
mlRe: NSTreeController problems Jonathan Dann May 19, 00:47
mlRe: NSTreeController problems Charles Srstka May 19, 00:57
mlRe: NSTreeController problems Jonathan Dann May 19, 01:44
mlRe: NSTreeController problems Charles Srstka May 19, 01:51