Изменить цвет выделения в NSTableView в Cocoa?

Я разрабатываю приложение Cocoa и столкнулся с проблемой выделения. Стандартный цвет подсветки в приложениях MAC OS X синий, но это не подходит для моего приложения, поскольку из-за концепций дизайна мне нужен зеленый цвет для выделения.

Я попытался подклассифицировать метод NSTableview и переопределить

- (void)highlightSelectionInClipRect:(NSRect)clipRect

но это не помогло.

Как решить эту проблему?

Ответы

Ответ 1

Я использую это, и до сих пор отлично работает:

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

Ответ 2

Я также искал часы для ответа на это, и хотя я нашел много фрагментов, ни один из них не был полным. Поэтому я предлагаю другой подход, который я использую с успехом.

1) Установите для параметра NSTableViewHighLightStyle значение 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 и внесите itDisplayCell.

Это позволит вам изменить 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];
        }
    }
}

И все готово.

Ответ 3

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

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

    }
}

Я использую этот код для работы с высотой, код в моем пользовательском файле ячейки