Cocoa: willDisplayCell delegate method of NSTableView, [NSCell setTextColor], and “source lists”
Mac OS 10.5 added a “source list” highlighting style to NSTableView, with the API below for your reference:
enum {
NSTableViewSelectionHighlightStyleRegular = 0,
NSTableViewSelectionHighlightStyleSourceList = 1,
};
typedef NSInteger NSTableViewSelectionHighlightStyle;
- (NSTableViewSelectionHighlightStyle)selectionHighlightStyle;
- (void)setSelectionHighlightStyle:(NSTableViewSelectionHighlightStyle)selectionHighlightStyle;
Source lists should have bold text when the item is selected, and NSTableView attempts to auto-format the cell’s contents to automatically do this for you, as seen in this screen shot for the selected item in the open panel source list:

However, the code that does this formatting does so by converting the ’stringValue’ of the cell to an attributedStringValue that has the bold text. This is done *before* calling the delegate with “willDisplayCell”. The delegate gets the final say of how it looks in “willDisplayCell”, but this can cause unexpected results if you want to do something like this:
- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
if(row == 0) {
[cell setTextColor: [NSColor redColor]];
} else {
[cell setTextColor: [NSColor blackColor]];
}
}
The problem with the above code is that it is *too late* for the coloring to be correctly applied to the cell if it is selected. The work around is easy; you need to color the cell text earlier, and a perfect place to do that is in the new 10.5 delegate method “dataCellForTableColumn:”
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSTextFieldCell *cell = [tableColumn dataCell];
if(row == 0) {
[cell setTextColor: [NSColor redColor]];
} else {
[cell setTextColor: [NSColor blackColor]];
}
return cell;
}
Cool. Have fun.
January 9th, 2008 at 1:13 pm
sorry; i know my code autoformatting is horrid. some day i’ll fix it up..
January 11th, 2008 at 8:08 am
Hmm, that’s not really cool. That’s a bug that should be fixed by Apple.
January 11th, 2008 at 8:41 am
This is not a bug! Please consider how it is done, and how it should work. The new highlighting style, NSTableViewSelectionHighlightStyleSourceList, does auto-formatting to the cells, which was *never* done before. Specifically, it bolds the text, and the only way to do this is to convert a string to an attributed string with the NSFontAttributeName applied. This is done *before* willDisplayCell so you, the developer, has a chance to change it to whatever you want. You can change the string at that time, or set the string value back to a plain string. We can’t simply set the font, since it would be incorrectly set for that cell, which would cause other rows to draw with the wrong font. In the end, it is the best solution with the least amount of work from the developer.
I’m curious as to exactly why you think this is a bug? It is documented that we autoformat the contents in the AppKit release notes.
June 2nd, 2008 at 4:37 pm
another work around would be to return an attributed string from the datasource method that included the appropriate colors.