在Cocoa中更改NSTableView中的突出显示颜色?

时间:2011-08-12 09:20:07

标签: objective-c cocoa nstableview highlighting

我正在开发一个Cocoa应用程序,并遇到突出显示问题。 MAC OS X应用程序中的标准突出显示颜色为蓝色,但它不适合我的应用程序,因为由于设计概念,我需要绿色来突出显示。

我试图继承NSTableview并覆盖方法

- (void)highlightSelectionInClipRect:(NSRect)clipRect

但它没有帮助。

如何解决这个问题?

3 个答案:

答案 0 :(得分:19)

我正在使用它,到目前为止完美无缺:

- (void)highlightSelectionInClipRect:(NSRect)theClipRect
{

        // this method is asking us to draw the hightlights for 
        // all of the selected rows that are visible inside theClipRect

        // 1. get the range of row indexes that are currently visible
        // 2. get a list of selected rows
        // 3. iterate over the visible rows and if their index is selected
        // 4. draw our custom highlight in the rect of that row.

    NSRange         aVisibleRowIndexes = [self rowsInRect:theClipRect];
    NSIndexSet *    aSelectedRowIndexes = [self selectedRowIndexes];
    int             aRow = aVisibleRowIndexes.location;
    int             anEndRow = aRow + aVisibleRowIndexes.length;
    NSGradient *    gradient;
    NSColor *       pathColor;

        // if the view is focused, use highlight color, otherwise use the out-of-focus highlight color
    if (self == [[self window] firstResponder] && [[self window] isMainWindow] && [[self window] isKeyWindow])
    {
        gradient = [[[NSGradient alloc] initWithColorsAndLocations:
                     [NSColor colorWithDeviceRed:(float)62/255 green:(float)133/255 blue:(float)197/255 alpha:1.0], 0.0, 
                     [NSColor colorWithDeviceRed:(float)48/255 green:(float)95/255 blue:(float)152/255 alpha:1.0], 1.0, nil] retain]; //160 80

        pathColor = [[NSColor colorWithDeviceRed:(float)48/255 green:(float)95/255 blue:(float)152/255 alpha:1.0] retain];
    }
    else
    {
        gradient = [[[NSGradient alloc] initWithColorsAndLocations:
                     [NSColor colorWithDeviceRed:(float)190/255 green:(float)190/255 blue:(float)190/255 alpha:1.0], 0.0, 
                     [NSColor colorWithDeviceRed:(float)150/255 green:(float)150/255 blue:(float)150/255 alpha:1.0], 1.0, nil] retain];

        pathColor = [[NSColor colorWithDeviceRed:(float)150/255 green:(float)150/255 blue:(float)150/255 alpha:1.0] retain];
    }

        // draw highlight for the visible, selected rows
    for (aRow; aRow < anEndRow; aRow++)
    {
        if([aSelectedRowIndexes containsIndex:aRow])
        {
            NSRect aRowRect = NSInsetRect([self rectOfRow:aRow], 1, 4); //first is horizontal, second is vertical
            NSBezierPath * path = [NSBezierPath bezierPathWithRoundedRect:aRowRect xRadius:4.0 yRadius:4.0]; //6.0
                [path setLineWidth: 2];
                [pathColor set];
                [path stroke];

            [gradient drawInBezierPath:path angle:90];
        }
    }
}

答案 1 :(得分:10)

我也搜索了几个小时的答案,尽管我发现了许多碎片,但没有一个是完整的。所以我在这里提交另一种方法,我正在成功使用它。

1)将NSTableView selectionHighLightStyle设置为None

这是必要的,以确保OSX不会简单地将它自己的亮点应用到你的顶部,留下一个蓝色突出显示。

您可以通过IB或代码执行此操作。

2)子类NSTableView,并覆盖drawRow。

这会将所选行的背景颜色设置为主要(活动窗口)和辅助(非活动)。

- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
{
    NSColor* bgColor = Nil;

    if (self == [[self window] firstResponder] && [[self window] isMainWindow] && [[self window] isKeyWindow])
    {
        bgColor = [NSColor colorWithCalibratedWhite:0.300 alpha:1.000];
    }
    else
    {
        bgColor = [NSColor colorWithCalibratedWhite:0.800 alpha:1.000];
    }

    NSIndexSet* selectedRowIndexes = [self selectedRowIndexes];
    if ([selectedRowIndexes containsIndex:row])
    {
        [bgColor setFill];
        NSRectFill([self rectOfRow:row]);
    }
    [super drawRow:row clipRect:clipRect];
}

3)实现NSTableViewDelegate,将其附加到NSTableView,并实现willDisplayCell。

这将允许您在选择/取消选择时更改行的textColor,以防您的选择颜色使文本难以阅读。

- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
    // check if it is a textfield cell
    if ([aCell isKindOfClass:[NSTextFieldCell class]])
    {
        NSTextFieldCell* tCell = (NSTextFieldCell*)aCell;
        // check if it is selected
        if ([[aTableView selectedRowIndexes] containsIndex:rowIndex])
        {
            tCell.textColor = [NSColor whiteColor];
        }
        else
        {
            tCell.textColor = [NSColor blackColor];
        }
    }
}

你已经完成了。

答案 2 :(得分:2)

- (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView *)controlView
{

    if ([self isHighlighted])
    {
        NSRect bgFrame = frame;
        [[NSColor redColor] set];  
        NSRectFill(bgFrame);

    }
}

我使用此代码来处理高度,代码在我的自定义单元格文件中