我有一个绑定到我的NSTreeController的NSOutlineView。使用以下命令使用数据设置NSTreecontroller(myTreeController)的内容: [self.myTreeController setContent:self.myArrayOfFiles]; 该数组的内容由NSTreeNode父对象和使用NSTreeNode子类(TKnode)添加的子对象组成:
[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
}
这可以工作并返回一个包含我所有对象的数组,而不是NSTreeNodes,但是我感兴趣的对象。但是我似乎很容易在一个对象上有时两次调用representObject来访问我的对象。这是我应该使用NSTReeController和NSTreeNodes的方式吗?有没有更好的办法?我首先想要使用NSTreeNode和NSTreeController的原因是为了获得一些已经实现的免费方法,例如sort和arrangeObjects,我习惯使用NSTableView。但是我用来访问NSTreeController内容的方法似乎不正确?我应该使用arrangedObjects
来获取NSTReeController的内容还是应该使用不同的方法?任何有关如何正确展平NSOutlineView的建议都非常受欢迎。
谢谢!干杯,特隆德
答案 0 :(得分:1)
这个问题原来是一个真正的风滚草(我一个月内的第二个),所以我想跟进一些更多的信息。我最终使用上面发布的代码来展平我的NSOutlineView,因为我无法找到更好的选择。当你必须递归迭代未知数量的子文件夹(在我的情况下)时,这似乎是每次达到更深层次时调用descendants
方法的最佳选项。我发现了一个非常有用的网站,其中包含许多有用的NSTreeController扩展here,它使用的方法与我采用的方法相同。除非有人帮我找出一个更快更好的算法来展平NSTreeController的arrangeObjects,我相信我会坚持这种方法。
干杯,特隆德
更新:在解决方案问题之后,我决定发布我的方法来展平大纲视图。我希望他能帮助别人。
- (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]];
}
}
答案 1 :(得分:0)
从我刚写的另一个答案中看出这个链接。如果扩展/显示树中的所有内容,则可以使用:
for (NSUInteger row = 0; row < [outlineView numberOfRows]; row++)
{
NSTreeNode* node = [outlineView itemAtRow:row];
[nodeArray addObject:node];
}
outlineView的行基本上是一个扁平的树。而且你可以扩展每个项目,同时迭代以获得所有项目。