Change selection color on view-based NSTableView

| | August 5, 2015

Standard highlighting color in OS X applications is blue.

Is it possible to change it to another color, e.g. gray?

Note that I am using the new view-based NSTableView available starting from OS X 10.7.

9 Responses to “Change selection color on view-based NSTableView”

  1. If you don’t need any custom draws, then subclasses NSTableRowView is a bit too much. You can set the background color directly using NSTableView‘s delegate didAddRowView:

    - (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
        if (/* A condition to fill in order to change the background color */) {
            rowView.backgroundColor = [NSColor redColor];
        }
    }
    

    Note: that will work only for NSView-based table views.

  2. Some modifications to Jean-Pierre answer

    Use the following code in response to the NSTableViewDelegate protocol tableViewSelectionDidChange:

    Get the NSTableRowView for the selected row and call the method setEmphasized on it. When setEmphasized is set to YES you get the blue highlight, when NO you get the gray highlight.

    -(void)tableViewSelectionDidChange:(NSNotification *)aNotification {
    
     NSInteger selectedRow = [myTableView selectedRow];
     NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
    [myRowView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
    [myRowView setEmphasized:NO];
    }
    

    And to avoid dancing effect of blue then gray set

    [_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
    
  3. When using Swift you can do this on 10.10 for view based Cells

    Subclass the NSTableCellView and implement this:

    //override to change background color on highlight
    override var backgroundStyle:NSBackgroundStyle{
        //check value when the style was setted
        didSet{
            //if it is dark the cell is highlighted -> apply the app color to it
            if backgroundStyle == .Dark{
                self.layer!.backgroundColor = yourColor
            }
            //else go back to the standard color
            else{
                self.layer!.backgroundColor = NSColor.clearColor().CGColor
            }
        }
    }
    

    Note that the NSTableView highlight style must be set to Regular if it is on SourceList it will cause some strange clipping.

    This is not the cleanest solution but it works good on yosemite

  4.   Use this Notification for NSTableView:
    
              - (void)tableViewSelectionDidChange:(NSNotification *)notification
                {
    
                     //You Logic stuff
                 }
    
  5. Dipak Narigara on November 30, -0001 @ 12:00 AM
    - (void)tableViewSelectionDidChange:(NSNotification *)notification
    {
        [tblCategory enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row){
            CustomMainCell *cellView = [rowView viewAtColumn:0];
            if(rowView.selected){
                cellView.txtFieldTitle.textColor=[NSColor colorWithCalibratedRed:245.0/255.0 green:110.0/255.0 blue:65.0/255.0 alpha:1.0];
            }else{
                cellView.txtFieldTitle.textColor=[NSColor whiteColor];
            }
        }];
    }
    

    [tblCategory setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];

  6. Use the following code in response to the NSTableViewDelegate protocol tableViewSelectionDidChange:

    Get the NSTableRowView for the selected row and call the method setEmphasized on it.
    When setEmphasized is set to YES you get the blue highlight, when NO you get the gray highlight.

    -(void)tableViewSelectionDidChange:(NSNotification *)aNotification {
    
         NSInteger selectedRow = [myTableView selectedRow];
         NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO];
         [myRowView setEmphasized:NO];
    }
    
  7. You have to subclass NSTableView, and rewrite the functions below in order to change the alternating colors.

    • (void) drawRow: (NSInteger) row clipRect: (NSRect) clipRect

    • (void) drawBackgroundInClipRect: (NSRect) clipRect ** This one to change the main and alternate color **

    Use a for loop and insert this conditional (i % 2 == 0) to detect odd and even rows.

  8. Since you’re using the view based NSTableView, you can subclass NSTableRowView, feed it to the table delegate method - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row;, then customize your selection in the row view class.

    Here’s an example:

    - (void)drawSelectionInRect:(NSRect)dirtyRect {
        if (self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone) {
            NSRect selectionRect = NSInsetRect(self.bounds, 2.5, 2.5);
            [[NSColor colorWithCalibratedWhite:.65 alpha:1.0] setStroke];
            [[NSColor colorWithCalibratedWhite:.82 alpha:1.0] setFill];
            NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:6 yRadius:6];
            [selectionPath fill];
            [selectionPath stroke];
        }
    }
    
  9. Ankit Srivastava on November 30, -0001 @ 12:00 AM

    It seems to me there is an option available to change this coz the documentation says three selection style and the default style in regular is blue, look at the image below.. you need to send it a message which I cant figure out as I have never developed apps for mac before.. hoping this helps…!

    enter image description here

Leave a Reply