Given model objects that NSTreeController
represents, how do you find their index paths in the tree and subsequently select them? This seems to be a blindingly obvious problem, but I can't seem to find any reference to it. Any ideas?
Given model object, how to find index path in NSTreeController?
Asked Answered
There's no "easy" way, you have to walk the tree nodes and find a matching index path, something like:
Objective-C:
Category
@implementation NSTreeController (Additions)
- (NSIndexPath*)indexPathOfObject:(id)anObject
{
return [self indexPathOfObject:anObject inNodes:[[self arrangedObjects] childNodes]];
}
- (NSIndexPath*)indexPathOfObject:(id)anObject inNodes:(NSArray*)nodes
{
for(NSTreeNode* node in nodes)
{
if([[node representedObject] isEqual:anObject])
return [node indexPath];
if([[node childNodes] count])
{
NSIndexPath* path = [self indexPathOfObject:anObject inNodes:[node childNodes]];
if(path)
return path;
}
}
return nil;
}
@end
Swift:
Extension
extension NSTreeController {
func indexPathOfObject(anObject:NSObject) -> NSIndexPath? {
return self.indexPathOfObject(anObject, nodes: self.arrangedObjects.childNodes)
}
func indexPathOfObject(anObject:NSObject, nodes:[NSTreeNode]!) -> NSIndexPath? {
for node in nodes {
if (anObject == node.representedObject as! NSObject) {
return node.indexPath
}
if (node.childNodes != nil) {
if let path:NSIndexPath = self.indexPathOfObject(anObject, nodes: node.childNodes)
{
return path
}
}
}
return nil
}
}
Ouch, that's really inefficient. I'm thinking of writing a subclass of treecontroller that keeps a mapping between model and treenodes. Or perhaps a category on the model that keeps references to the associated treenode. –
Dehumidify
All you'd need to do in your subclass is to maintain a flat
NSMutableArray
of the tree nodes. You'd need to be careful that all modifications of the nodes are reflected in your array, of course. –
Insert Hmm, I was thinking of a
NSMutableDictionary
mapping either the model object or the objectID to NSTreeNode
s, since it seems more efficient for lookup. Is there any reason NSmutableArray
might work betteR? –
Dehumidify NSMutableDictionary
would work fine. I would tend to store the NSIndexPath
of the items rather than the tree node because I'm not sure if its guaranteed that NSTreeController
always returns the same NSTreeNode
per object. –
Insert @Dehumidify Did you implement this then? –
Halfmoon
Why not use the NSOutlineView to get the parent items like this:
NSMutableArray *selectedItemArray = [[NSMutableArray alloc] init];
[selectedItemArray addObject:[self.OutlineView itemAtRow:[self.OutlineView selectedRow]]];
while ([self.OutlineView parentForItem:[selectedItemArray lastObject]]) {
[selectedItemArray addObject:[self.OutlineView parentForItem:[selectedItemArray lastObject]]];
}
NSString *selectedPath = @".";
while ([selectedItemArray count] > 0) {
OBJECTtype *singleItem = [selectedItemArray lastObject];
selectedPath = [selectedPath stringByAppendingString:[NSString stringWithFormat:@"/%@", singleItem.name]];
selectedItemArray removeLastObject];
}
NSLog(@"Final Path: %@", selectedPath);
This will output: ./item1/item2/item3/...
I'm assuming you are looking for a file path here but you can adjust for whatever your data source may represent.
The question is looking for an NSIndexPath for any given object in the tree, so that you can change the tree controller's selectedIndexPath(s) to that one programmatically. You are assuming that the object is already selected. If so, you'd just get the selectionIndexPath from the tree controller! –
Glidden
© 2022 - 2024 — McMap. All rights reserved.