NSOutlineView:删除显示三角形和缩进

ind*_*gie 26 cocoa objective-c nsoutlineview nstreecontroller

我正在使用NSOutlineView进行项目,似乎无法弄清楚两件事:

  • 如何删除树节点的显示三角形.像iTunes这样的应用似乎能够做到这一点:

替代文字

是否有某种用于此的NSOutlineView Delegate方法?或者它需要一个子类?

  • 如何禁用项目的缩进.我尝试使用setIndentationPerLevel:并将其设置为0,以及在Interface Builder中将列缩进更改为0,但它似乎没有任何效果.

Mar*_*ann 41

你在这里遇到了合适的人选.一周前我不得不解决这个问题.

删除显示三角形:frameOfOutlineCellAtRow:NSOutlineView子类中实现该方法并返回NSZeroRect(当然,只有当您想要隐藏该特定行的三角形时).

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {
    return NSZeroRect;
}
Run Code Online (Sandbox Code Playgroud)

禁用缩进:大纲视图的标准布局保留最左侧的空间以绘制三角形,以防项目可扩展.但您可以通过指定不同的绘图框来覆盖单个项目.您也可以通过响应此消息在子类中执行此操作:

- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
    NSRect superFrame = [super frameOfCellAtColumn:column row:row];


    if ((column == 0) /* && isGroupRow */) {
        return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height);
    }
    return superFrame;
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过将 indentationMarkerFollowsCell 设置为 false 来影响缩进,而无需继承大纲视图。 (2认同)

Tam*_*ege 37

对于未来的参考,隐藏在扩张三角形最干净和最简单的方法NSOutlineView项目是通过实现outlineView:shouldShowOutlineCellForItem:该方法NSOutlineViewDelegate在委托协议:

-(BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item
{
    // replace this with your logic to determine whether the
    // disclosure triangle should be hidden for a particular item
    return [item hidesDisclosureTriangle];
}
Run Code Online (Sandbox Code Playgroud)

  • 当我尝试这样做时,我不再能够(以编程方式)折叠这些项目.这是我的错误吗? (4认同)
  • 似乎没有为基于视图的outlineviews调用此委托方法.在那种情况下,我发现在IB中将缩进设置为0具有所需的效果 (3认同)

And*_*sov 8

我必须结合上面的两种方法,因为outlineView:shouldShowOutlineCellForItem:单独不会删除为显示三角形保留的空间(它确实删除了三角形本身).

代表:

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {
    return NO;
}
Run Code Online (Sandbox Code Playgroud)

NSOutlineView的子类:

@implementation ExpandedOutlineView

#define kOutlineCellWidth 11
#define kOutlineMinLeftMargin 6

- (NSRect)frameOfCellAtColumn:(NSInteger)column row:(NSInteger)row {
    NSRect superFrame = [super frameOfCellAtColumn:column row:row];
    if (column == 0) {
        // expand by kOutlineCellWidth to the left to cancel the indent
        CGFloat adjustment = kOutlineCellWidth;

        // ...but be extra defensive because we have no clue what is going on here
        if (superFrame.origin.x - adjustment < kOutlineMinLeftMargin) {
            NSLog(@"%@ adjustment amount is incorrect: adjustment = %f, superFrame = %@, kOutlineMinLeftMargin = %f", NSStringFromClass([self class]), (float)adjustment, NSStringFromRect(superFrame), (float)kOutlineMinLeftMargin);
            adjustment = MAX(0, superFrame.origin.x - kOutlineMinLeftMargin);
        }

        return NSMakeRect(superFrame.origin.x - adjustment, superFrame.origin.y, superFrame.size.width + adjustment, superFrame.size.height);
    }
    return superFrame;
}

@end
Run Code Online (Sandbox Code Playgroud)

结果:

没有顶级缩进的NSOutlineView的屏幕截图