NSOutlineView 更改披露图像

发布于 2024-10-17 21:18:38 字数 789 浏览 2 评论 0原文

在我的大纲视图中,我正在添加自定义单元格,要绘制自定义单元格,我正在参考 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 是展开还是折叠,以便我可以相应地设置图像,

这只是更改公开图像的地方吗?

I my outline view, i am adding Custom cell, To drawing custom cell, i am referring example code , present in the Cocoa documentation

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

I want to change the disclosure image of the cell with my custom image, i have tried following things

- (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];
            }
        }
}

but that too not working, Is there any other way to change the disclosure image,
also how can i find out in willDisplayCell whether Item is expand or collapse, so i can set the image accordingly,

Is this only the place to change the disclosure image ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏日落 2024-10-24 21:18:38

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

我发现的最简单的解决方案如下,在大多数情况下应该有效。

该解决方案的另一个好处是系统可以自动处理许多其他情况,例如柱移动等,而无需您的参与。

- (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"]];
}

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

After researching this issue myself, and trying some of the answers here, I have found that the other approaches mentioned will work, but will require that you perform a lot more manual intervention in order to avoid screen artifacts and other strange behavior.

The simplest solution I found is the following, which should work in most cases.

This solution has the added benefit of the system automatically handling a great many other cases, such as column movement, etc, without your involvement.

- (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"]];
}

In your case, you would wrap this up with your class detection logic, and set the cell images appropriately for your cases.

や莫失莫忘 2024-10-24 21:18:38

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

在带有 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;
}

A nice way to change the disclosure image is to use a view based outline view:

In your ViewController with NSOutlineViewDelegate:

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

    return cell;
}

You have to subclass your NSOutlineView and overide the method:

- (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;
}
情绪失控 2024-10-24 21:18:38

适合寻找 Swift2 解决方案的人。子类化你的outlineview的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")
    }
}

For who looks for Swift2 Solution. Subclass NSRow of your outlineview and override didAddSubview method as below.

override func didAddSubview(subview: NSView) {
    super.didAddSubview(subview)
    if let sv = subview as? NSButton {
        sv.image = NSImage(named:"IconNameForCollapsedState")
        sv.alternateImage = NSImage(named:"IconNameForExpandedState")
    }
}
別甾虛僞 2024-10-24 21:18:38

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

- (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 状态应该介于两者之间。混合状态可确保您仍然获得打开和关闭动画。

You've got the basic idea but what you will need to do is draw the image yourself. Here's the code I use:

- (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];
}

You will need 3 different images as you can see, one for the ON state, one for the OFF state and also one for the MIXED state which should be halfway between the two. The mixed state makes sure you still get the opening and closing animation.

岁月流歌 2024-10-24 21:18:38

这是我到目前为止所尝试和工作的,

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

- (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] 是检查其是否为组。
但有一个问题,现在看起来像我需要做的鼠标处理:(,双击组行不会切换

This is what i have tried and working so far,

/* because we are showing our own disclose and expand button */

- (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;
}

I have subclassed NSOutlineView class and override these methods,

[self isGroupItem] is to check whether its group or not.
but got one problem, now looks like mousehandling i need to do :( , on double clicking group row is not toggling

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文