4

我的大纲视图,我正在添加自定义单元格,要绘制自定义单元格,我指的是示例代码,出现在 Cocoa 文档中

http://www.martinkahr.com/2007/05/04/nscell-image-and-text-sample/

我想用我的自定义图像更改单元格的公开图像,我尝试了以下操作

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item 
    {
        if([item isKindOfClass:[NSValue class]])
        {
            MyData *pDt = (MyData *)[item pointerValue];
            if(pDt->isGroupElement())
            {
                [cell setImage:pGroupImage];
            }
        }
}

但这也不起作用,有没有其他方法可以更改公开图像,以及如何在 willDisplayCell 中找出 Item 是展开还是折叠,以便我可以相应地设置图像,

这只是更改披露图像的地方吗?

4

5 回答 5

5

在自己研究了这个问题并尝试了这里的一些答案之后,我发现提到的其他方法也可以,但是需要您执行更多的手动干预以避免屏幕伪影和其他奇怪的行为。

我找到的最简单的解决方案如下,它应该在大多数情况下都有效。

该解决方案具有系统自动处理许多其他情况的额外好处,例如色谱柱移动等,无需您参与。

- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell
     forTableColumn:(NSTableColumn *)tableColumn
               item:(id)item
{
    [cell setImage:[NSImage imageNamed: @"Navigation right 16x16 vWhite_tx"]];
    [cell setAlternateImage:[NSImage imageNamed: @"Navigation down 16x16 vWhite_tx"]];
}

在您的情况下,您将使用您的类检测逻辑将其包装起来,并为您的情况适当地设置单元格图像。

于 2013-03-06T23:05:17.937 回答
3

更改公开图像的一个好方法是使用基于视图的大纲视图:

在带有 NSOutlineViewDelegate 的 ViewController 中:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
    CustomNSTableCellView *cell    = [outlineView makeViewWithIdentifier:tableColumn.identifier owner:self];
    cell.item                      = item;

    return cell;
}

您必须继承您的 NSOutlineView 并覆盖该方法:

- (id)makeViewWithIdentifier:(NSString *)identifier owner:(id)owner
{
    id view = [super makeViewWithIdentifier:identifier owner:owner];

    if ([identifier isEqualToString:NSOutlineViewDisclosureButtonKey])
    {
        // Do your customization
        // return disclosure button view

        [view setImage:[NSImage imageNamed:@"Disclosure_Categories_Plus"]];
        [view setAlternateImage:[NSImage imageNamed:@"Disclosure_Categories_Minus"]];
        [view setBordered:NO];
        [view setTitle:@""];

        return view;
    }

    return view;
}

//Frame of the disclosure view
- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row
{
    NSRect frame = NSMakeRect(4, (row * 22), 19, 19);
    return frame;
}
于 2015-02-10T14:47:14.570 回答
2

适合寻找 Swift2 解决方案的人。您的大纲视图的子类 NSRow 并覆盖 didAddSubview 方法,如下所示。

override func didAddSubview(subview: NSView) {
    super.didAddSubview(subview)
    if let sv = subview as? NSButton {
        sv.image = NSImage(named:"IconNameForCollapsedState")
        sv.alternateImage = NSImage(named:"IconNameForExpandedState")
    }
}
于 2016-09-05T12:54:43.110 回答
1

你已经有了基本的想法,但你需要做的是自己绘制图像。这是我使用的代码:

- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSString *theImageName;
    NSInteger theCellValue = [cell integerValue];
    if (theCellValue==1) {
        theImageName = @"PMOutlineCellOn";
    } else if (theCellValue==0) {
        theImageName = @"PMOutlineCellOff";
    } else {
        theImageName = @"PMOutlineCellMixed";
    }

    NSImage *theImage = [NSImage imageNamed: theImageName];
    NSRect theFrame = [outlineView frameOfOutlineCellAtRow:[outlineView rowForItem: item]];
    theFrame.origin.y = theFrame.origin.y +17;
    // adjust theFrame here to position your image
    [theImage compositeToPoint: theFrame.origin operation:NSCompositeSourceOver];
    [cell setImagePosition: NSNoImage];
}

如您所见,您将需要 3 张不同的图像,一张用于ON状态,一张用于OFF状态,还有一张用于MIXED状态,应该介于两者之间。混合状态确保您仍然可以获得打开和关闭动画。

于 2011-02-18T07:38:28.617 回答
0

这是我迄今为止尝试和工作的,

/* 因为我们展示了我们自己的披露和展开按钮 */

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {

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

    if ((column == 0) && ([self isGroupItem:[self itemAtRow:row]])) {
        return NSMakeRect(0, superFrame.origin.y, [self bounds].size.width, superFrame.size.height);
    }
    return superFrame;
}

我继承了 NSOutlineView 类并覆盖了这些方法,

[self isGroupItem] 是检查它是否是组。但是有一个问题,现在看起来我需要做鼠标处理:(,在双击组行时没有切换

于 2011-02-18T12:54:18.830 回答