NSOutlineView仅显示NSTreeController层次结构的前2个级别

时间:2015-05-08 11:45:15

标签: objective-c macos cocoa

我正在使用NSOUtlineView填充NSTreeController

NSTreeController是一个3级层次结构控制器(CBMovie,CBDisc和CBEpisode),但只有前2个级别显示在大纲视图中。

所有对象的实现都是相同的:我已经实现了指定子项的方法,子计数以及对象是否为叶子。正确地为所有对象调用这些方法(对于那些未显示的对象,孙子:CBEpisode)。

在大纲视图中,前两个级别的所有内容都正确显示。但孙子从未展示过,我没有选择扩展他们的父母来看他们。我只能看到CBMovie和CBDiscs。

我想知道是否还有其他设置我缺少关于NSTreeControllers或NSOutlineView配置中节点扩展的深度。

下面:在三个节点之一中实现。 每个节点类具有与其子节点不同的路径。这在 - (NSArray *)children方法中指定(正确调用)。

-(NSArray*)children
{
    return [[self Episodes] allObjects];
}

-(int)childrenCount
{
    return [[self Episodes] count];
}

-(BOOL)isLeaf
{
    return ![[self Episodes] count];
}

输出日志代码。数据源NSTreeController似乎具有正确的结构。

   CBMovie
      CBDisc
         CBEpisode
         CBEpisode
    CBMovie
       CBDisc
       CBDisc
       CBDisc
       CBDisc
    CBMovie
       CBDisc
           CBEpisode
           CBEpisode

这就是我填充NSOutlineView(基于单元格)的方式。我不使用数据源方法,但我以编程方式绑定它。

NSMutableDictionary *bindingOptions = [[NSMutableDictionary alloc] initWithCapacity:2];

        if (metadata.valueTransformer) {
            [bindingOptions setObject:metadata.valueTransformer forKey:NSValueTransformerNameBindingOption];
        }
        [bindingOptions setObject:[NSNumber numberWithBool:NO] forKey:NSCreatesSortDescriptorBindingOption];
        [bindingOptions setObject:[NSNumber numberWithBool:NO] forKey:NSRaisesForNotApplicableKeysBindingOption];

        [newColumn bind:@"value" toObject:currentItemsArrayController withKeyPath:[NSString stringWithFormat:@"arrangedObjects.%@", metadata.columnBindingKeyPath] options:bindingOptions];

2 个答案:

答案 0 :(得分:1)

检查NSTreeController

  

NSTreeController是一个3级层次结构控制器,但只有前2个级别显示在大纲视图中。

您确认已将所有三个级别加载到NSTreeController?您可以通过将其内容记录到控制台并使用下面的扩展名来完成此操作。如果此代码生成的输出与大纲视图中显示的输出匹配,则问题可能在NSTreeController侧,而不是大纲视图。

#import "NSTreeController+Logging.h"

@implementation NSTreeController (Logging)

// Make sure this is declared in the associated header file.
-(void)logWithBlock:(NSString * (^)(NSTreeNode *))block {

    NSArray *topNodes = [self.arrangedObjects childNodes];
    [self logNodes:topNodes withIndent:@"" usingBlock:block];
}

// For internal use only.
-(void)logNodes:(NSArray *)nodes
     withIndent:(NSString *)indent
     usingBlock:(NSString * (^)(NSTreeNode *))block {

    for (NSTreeNode * each in nodes) {
        NSLog(@"%@%@", indent, block(each));
        NSString *newIndent = [NSString stringWithFormat:@"  %@", indent];
        [self logNodes:each.childNodes withIndent:newIndent usingBlock:block];
    }
}

@end

上面的代码不需要调整,您需要做的就是使用自定义块调用它:

-(void)logIt {

    [self.treeController logWithBlock:^NSString *(NSTreeNode * node) {

        // This will be called for every node in the tree. This implementation
        // will see the object's description logged to the console - you may
        // want to do something more elaborate.
        NSString *description = [[node representedObject] description];
        return description;
    }];

}

检查NSOutlineView

如果所有数据似乎已正确加载到NSTreeController,您可以查看NSOutlineView的填充方式。委托方法-[NSOutlineViewDelegate outlineView:viewForTableColumn:item]是一个很好的起点。 item参数是NSTreeNode实例,因此,在返回相关视图之前,您可以查看此节点并确保它的行为符合预期。在您的情况下,您应该仔细检查代表item个对象的CBDisc个对象的属性。 (您可能需要单击“公开”按钮以使此方法为相关对象触发。)

-(NSView *)outlineView:(NSOutlineView *)outlineView
    viewForTableColumn:(NSTableColumn *)tableColumn
                  item:(id)item {

    NSTreeNode *node = (NSTreeNode *)item;
    NSManagedObject *representedObject = (NSManagedObject *)node.representedObject;

    // Query the node
    NSLog(@"%@ <%@>", representedObject.description, [representedObject class]);
    NSLog(@"  node is a leafNode: %@", node.isLeaf ? @"YES" : @"NO");
    NSLog(@"  node has child-count of: %lu", (unsigned long)node.childNodes.count);

    // Query the NSManagedObject
    // your stuff here...

    // This is app-specific - you'll probably need to change the identifier.
    return [outlineView makeViewWithIdentifier:@"StandardTableCellView" owner:self];
}

答案 1 :(得分:0)

所以,我已经弄明白了为什么。

相当愚蠢:包含披露箭头的主要轮廓列仅为20px宽度,并且儿童的箭头有缩进。

我只使用了大纲列中的箭头,而不是节点的标题,这就是它如此狭窄的原因。

我已经禁用缩进,现在我可以看到所有箭头了。