2012-01-29 6 views
8

NSTreeControllerを表すモデルオブジェクトが与えられた場合、ツリー内のインデックスパスをどのように見つけ出し、その後それらを選択しますか?これは盲目的に明らかな問題だと思われますが、私はそれを参照することはできません。何か案は?ない "簡単な" 方法はありません与えられたモデルオブジェクトは、どのようにNSTreeControllerでインデックスパスを見つけるのですか?

答えて

18

、あなたはツリーノードを歩き、マッチング・インデックス・パスを見つける必要があり、何かのように:

のObjective-C:

カテゴリー

@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  

スイフト:

拡張

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 
    } 
} 
+1

これは本当に非効率的です。私はモデルとtreenodesの間のマッピングを保持するtreecontrollerのサブクラスを書くことを考えています。または、おそらくモデル上のカテゴリで、関連付けられたtreenodeへの参照を保持します。 – Tony

+0

サブクラスで行う必要があるのは、ツリーノードのフラットな 'NSMutableArray'を維持することだけです。もちろん、ノードのすべての変更がアレイに反映されるように注意する必要があります。 –

+0

ええと、モデルオブジェクトかobjectIDを 'NSTreeNode'にマッピングする' NSMutableDictionary'を考えていました。 'NSmutableArray'がbetteRを動かす理由はありますか? – Tony

-1

このような親アイテムを取得するためにNSOutlineViewを使用しない理由:

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); 

この出力は以下となります。./item1/item2/item3/...

を私はあなたがここでファイルパスを探していると仮定していますが、データソースが表すものが何であれ調整することができます。

+0

質問は、ツリー内の任意のオブジェクトのNSIndexPathを探しています。そのため、ツリーコントローラのselectedIndexPathをプログラムで変更することができます。オブジェクトがすでに選択されていると仮定しています。もしそうなら、ツリーコントローラからselectionIndexPathを取得するだけです! – stevesliva

関連する問題