I searched for hours for an answer on this as well, and although I found many fragments, none of them were complete. So here I submit another approach, which I am using with success.
1) Set your NSTableView selectionHighLightStyle to None
This is necessary to ensure that OSX does not simply apply it's own highlights over the top of yours, leaving you with a blue highlight.
You can do this either through IB or via code.
2) Subclass NSTableView, and override drawRow.
This will set the background color for your selected rows to primary (active window) and secondary (inactive).
- (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) Implement an NSTableViewDelegate, attach it to your NSTableView, and implement willDisplayCell.
This will allow you to change the textColor of the rows on selection/deselection, in case your selection colors make the text hard to read.
- (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];
}
}
}
And you are done.