0

我有一个绑定到我的 NSTreeController 的 NSOutlineView。NSTreecontroller (myTreeController) 的内容使用以下命令设置数据: [self.myTreeController setContent:self.myArrayOfFiles]; 数组的内容由使用 NSTreeNode 子类 (TKnode) 添加的 NSTreeNode 父对象和子对象组成:

[TKnode treeNodeWithRepresentedObject:myRootObject].

这很好用,可以正确显示我的 NSoutlineView。但是当我想遍历 NSOutlineView 的内容时,我需要将其展平并将对象存储在一个数组中。这是我需要一些帮助的地方,因为我拥有的解决方案不是最佳的并且可能容易出错。

我首先使用以下方法返回 NSTreeController 的内容:

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

这将返回一个包含树结构的大小为 1 的 NSTreeControllerTreeNode 数组。然后我使用 childNodes 方法访问树结构的第一层。

- (NSArray *)flattenedNodes
{
    NSMutableArray *mutableArray = [NSMutableArray array]; 
    for (TKnode *rootnode in [self rootNodes]){
        for (TKnode *node in [rootnode childNodes]){

            if (![[node representedObject] isLeaf]){
                [mutableArray addObjectsFromArray:[self descendants:[node representedObject]]];
            }
            else {
                [mutableArray addObject:[[node representedObject] representedObject]];
            }
        }
    }
    DLog(@"My files: %lu",[mutableArray count]);
    return [[mutableArray copy] autorelease];
}

使用以下方法递归访问子项的子项:

- (NSArray *)descendants:(TKnode *) node
{
    NSMutableArray *descendantsArray = [NSMutableArray array]; 
    for (TKnode *mynode in [node childNodes]) {

        [descendantsArray addObject:[mynode representedObject]];

        if (!mynode.isLeaf){
            [descendantsArray addObjectsFromArray:[self descendants:mynode]];
        }
    }
    return [[descendantsArray copy] autorelease]; // return immutable
}

这有效并返回一个数组,其中包含我的所有对象,而不是 NSTreeNode,而是我感兴趣的对象。但似乎很容易出错,我有时必须在对象上调用两次代表对象才能访问我的对象。这是我应该使用 NSTReeController 和 NSTreeNodes 的方式吗?有没有更好的办法?我首先想使用 NSTreeNode 和 NSTreeController 的原因是为了免费获得一些已经实现的方法,例如排序和排列对象,我习惯于使用 NSTableView。但是我用来访问 NSTreeController 内容的方法似乎不正确?我应该使用arrangedObjects来获取 NSTReeController 的内容还是应该使用不同的方法?非常感谢任何有关如何正确展平 NSOutlineView 的建议。

谢谢!干杯,特隆德

4

2 回答 2

1

这个问题原来是一个真正的风滚草(我一个月内的第二个)所以我想跟进一些更多信息。我最终使用上面发布的代码来展平我的 NSOutlineView,因为我找不到更好的选择。当您必须递归地遍历未知数量的子文件夹(在我的情况下)时,这似乎descendants是每次达到更深层次时调用该方法的最佳选择。我在这里找到了一个非常有用的网站,其中包含许多有用的 NSTreeController 扩展,它使用的方法与我采用的方法相同。除非有人帮助我找出一种更快更好的算法来扁平化 NSTreeController 的排列对象,否则我相信我会坚持使用这种方法。

干杯,特隆德

更新:在对解决方案提出问题后,我决定发布我的方法来展平大纲视图。我希望他能帮助别人。

- (void) flattenOutlineview
{
    NSMutableArray *nodeArray = [NSMutableArray array];
    [self.myFlattenedFiles removeAllObjects];
    [self.myFlattenedNodes removeAllObjects];
    [self.myIndexDict removeAllObjects];
    [nodeArray removeAllObjects];

    for (SDNode *rootnode in self.rootNodes)
    {
        [nodeArray addObject:rootnode];

        [self.myIndexDict setObject:[rootnode indexPath]
                             forKey:[[[rootnode representedObject] representedObject] fullpathL]];

        for (SDNode *node in [rootnode childNodes])
        {
            if (node.isLeaf){
                [nodeArray addObject:node];
                 [self.myIndexDict setObject:[node indexPath]
                                 forKey:[[[node representedObject] representedObject] fullPathCopy]];
            }
            else {
                [nodeArray addObjectsFromArray:[self descendants:node]];
                [self descendantsIndex:node];
           }  
       }  
   }
   [self.myFlattenedNodes setArray:[nodeArray copy]];

   for (SDNode *node in self.myFlattenedNodes)
   {
       [self.myFlattenedFiles addObject:[[node representedObject] representedObject]];
   }
}
于 2012-11-26T04:13:11.017 回答
0

从我刚刚写的另一个答案中看到了这个链接。如果您将树中的所有内容展开/显示,这将起作用:

for (NSUInteger row = 0; row < [outlineView numberOfRows]; row++)
{
    NSTreeNode* node = [outlineView itemAtRow:row];
    [nodeArray addObject:node];
}

outlineView 的行基本上是一棵扁平的树。您也许可以在迭代时扩展每个项目以获取所有项目。

于 2015-07-15T06:15:53.633 回答