本文介绍了如何在MAC OS X应用程序中更改NSTableView标头背景颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了所有找到的建议解决方案,但最终得到了最接近的解决方案:

I've tried all found suggested solutions but ended up with this as the closest:

目标是具有以下自定义颜色:

The target is to have custom color for:


  1. 完整的标题背景(例如绿色)

  2. 文本(例如白色)

  3. 排序控件颜色(例如白色)

当前,我只能正确设置内部bg和文本颜色,同时保留标题边框和将控件排序为默认白色。

Currently I can only set the interior bg and text color properly while leaving the header borders and sort controls in default white color.

我使用自定义 NCTableHeaderCell 的方法。

I use the approach of custom NCTableHeaderCell.

// <C> changing the bgColor doesn't work this way
[self.tv.headerView setWantsLayer:YES];
self.tv.headerView.layer.backgroundColor = NSColor.redColor.CGColor;

for (NSTableColumn *tc in self.tv.tableColumns) {

    // <C> this only helps to change the header text color
    tc.headerCell = [[NCTableHeaderCell_customizable alloc]initTextCell:@"Hdr"];

    // <C> this changes the bgColor of the area of the headerCell label text (the interior) but it leaves border and sort controls in white color;
    tc.headerCell.drawsBackground = YES;
    tc.headerCell.backgroundColor = NSColor.greenColor;

    // <C> changing the textColor doesn't work this way
    // <SOLUTION> use NCTableHeaderCell_customizable as done above;
    tc.headerCell.textColor = NSColor.redColor;
}

我的自定义类如下:

@implementation NCTableHeaderCell_customizable

// <C> this works as expected
- (NSColor *) textColor
{
    return NSColor.whiteColor;
}

// <C> this only sets the interior bgColor leaving the borders in standard color
//
//- (NSColor *) backgroundColor
//{
//    return NSColor.redColor;
//}

- (void) drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
{
    // <C> this only sets the interior bgColor leaving the borders in standard color
    //
    //self.backgroundColor = NSColor.orangeColor;

    [super drawWithFrame:cellFrame inView:controlView];

    // <C> this draws the red bg as expected but doesn't show the interior;
    //
    //    [NSColor.redColor set];
    //    NSRectFillUsingOperation(cellFrame, NSCompositingOperationSourceOver);

    // <C> this draws the red bg as expected but
    //     1) doesn't layout the interior well (I could fix this);
    //     2) doesn't show the sort controls (it's over-drawn with the code bellow);
    //
    //    [NSColor.redColor setFill];
    //    NSRectFill(cellFrame);
    //    CGRect titleRect = [self titleRectForBounds:cellFrame];
    //    [self.attributedStringValue drawInRect:titleRect];
}

- (void) drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
{
    [super drawInteriorWithFrame:cellFrame inView:controlView];
}

- (void) drawFocusRingMaskWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
{
    [super drawFocusRingMaskWithFrame:cellFrame inView:controlView];
}

- (void) drawSortIndicatorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView ascending:(BOOL)ascending priority:(NSInteger)priority;
{
    [super drawSortIndicatorWithFrame:cellFrame inView:controlView ascending:ascending priority:priority];
    //NSTableHeaderView *v = (NSTableHeaderView *)controlView;
}

我已经很接近解决方案了,但我不知道该怎么做正确绘制自定义标题单元格以归档目标。

I'm quite close to the solution but I don't know how to draw correctly the custom header cell to archive the goal.

推荐答案

感谢大家的帮助。我最终得到了这个简单的解决方案,该解决方案还解决了排序指示器。我放弃了自定义 NSHeaderCell 并通过单个自定义 NSTableHeaderRowView 方法解决了所有问题:

Thanks guys for your help. I've ended up with this simple solution which also solves the sort indicators. I've gave up on custom NSHeaderCell and resolved everything in single custom NSTableHeaderRowView method:

- (void)drawRect:(NSRect)dirtyRect
{
    [NSGraphicsContext saveGraphicsState];

    // Row: Fill the background
    //
    [NSColor.whiteColor setFill];
    const CGRect headerRect = CGRectMake(0.0, 1.0, self.bounds.size.width, self.bounds.size.height-1.0);
    [[NSBezierPath bezierPathWithRect:headerRect] fill];

    // Columns
    //
    for (NSUInteger i = 0; i < self.tableView.numberOfColumns; ++i) {
        NSRect rect = [self headerRectOfColumn:i];

        // separator on left
        //
        if (i != 0) {
            [[NSColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.35] setFill];
            [[NSBezierPath bezierPathWithRect:NSMakeRect(rect.origin.x, rect.origin.y+4.0, 1.0, rect.size.height-8.0)] fill];
        }

        NSTableColumn *tableColumn = self.tableView.tableColumns[i];
        NSSortDescriptor *col_sd = tableColumn.sortDescriptorPrototype;
        NSTableHeaderCell *tableHeaderCell = tableColumn.headerCell;

        // text
        //
        NSString *columnText = tableHeaderCell.stringValue;
        [columnText drawInRect:NSInsetRect(rect, 5.0, 4.0) withAttributes:nil];

        // sort indicator
        //
        for (NSInteger priority = 0; priority < self.tableView.sortDescriptors.count; ++priority) {
            NSSortDescriptor *sortDesciptor = self.tableView.sortDescriptors[priority];
            // <C> there is no way to get column from sortDesciptor so I use this trick comparing sortDesciptor with current column.sortDescriptorPrototype;
            // <C> not sure why sel_isEqual() dosn't work so I compare its string representation;
            if ([NSStringFromSelector(sortDesciptor.selector) isEqualToString:NSStringFromSelector(col_sd.selector)] == YES && [sortDesciptor.key isEqualToString:col_sd.key] == YES) {
                SDEBUG(LEVEL_DEBUG, @"sort-hdr", @"MATCH: sel=%@", NSStringFromSelector(sortDesciptor.selector));
                // <C> default implementation draws indicator ONLY for priority 0; Otherwise the indicator would have to graphically show the prio;
                // <C> it is a support for multi-column sorting;
                // <REF> shall you need it: https://stackoverflow.com/questions/46611972/sorting-a-viewbased-tableview-with-multiple-sort-descriptors-doesnt-work
                [tableHeaderCell drawSortIndicatorWithFrame:rect inView:self ascending:sortDesciptor.ascending priority:priority];
            }
        }
    }

    [NSGraphicsContext restoreGraphicsState];
}

这篇关于如何在MAC OS X应用程序中更改NSTableView标头背景颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 06:47