我有一个NSOutlineView绑定到我的NSTreeController。使用以下命令使用数据设置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
}
这可以正常工作并返回一个包含我所有对象的数组,而不是NSTreeNodes,而是包含我感兴趣的对象。但是似乎很容易出错,我有时必须在某个对象上两次调用presentatedObject才能访问我的对象。这是我应该使用NSTReeController和NSTreeNodes的方式吗?有没有更好的办法?首先,我想使用NSTreeNode和NSTreeController的原因是免费获得了一些已经实现的方法,例如sorting和rangedObjects,这些都是我习惯于NSTableView的。但是我用来访问NSTreeController内容的方法似乎不正确吗?我应该使用
arrangedObjects
来获取NSTReeController的内容还是应该使用其他方法?非常感谢有关如何正确展平NSOutlineView的任何建议。谢谢!干杯,特隆
最佳答案
这个问题原来是风滚草(我一个月来的第二个问题),所以我想跟进更多信息。由于找不到更好的选择,我最终使用了上面发布的代码来展平NSOutlineView。当您必须递归地遍历未知数目的子文件夹(在我的情况下)时,这似乎是最好的选择,每次您到达更深的层次时,都调用descendants
方法。我找到了一个非常有用的网站,其中包含许多有用的NSTreeController扩展here,它使用的方法与我采用的方法相同。除非有人帮助我找出一个更快,更好的算法来展平NSTreeController的rangedObjects,否则我相信我会坚持使用这种方法。
干杯,特隆
更新:在提出解决方案问题后,我决定发布有关如何展平Outlineview的方法。我希望他能帮助别人。
- (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]];
}
}