Custom selection/highlighting colors in a view based SourceList using a NSOutlineView (badge)

This post was published 11 years, 2 months ago. Some material it contains may no longer be applicable.

I’ve tried to implement the “Bubble” badges that Apple uses in many applications using a view based NSOutlineView, e.G. Mail:

Bildschirmfoto 2013-03-21 um 12.50.16

There are many solutions out there (see PXSourceList), but I wanted to use a view based approach this time.

Its no big deal creating the view, but when you start implementing the Badge you will face several problems. You may use a NSButton with inline style here, but if you start binding its title to your data things starting to go wrong as its clearly the wrong control for this case. So I decided to use a custom NSTextField with custom drawing.

Bildschirmfoto 2013-03-21 um 12.53.45

The main problem was the different drawing if the row is selected. You need to change your font- and background color. As a NSTextField, you do not know if you are highlighted or not and so you can’t do that. After some digging in the documentation if found the solution:

The enclosing NSTableCellView gives its subviews a “hint” how it should draw itself. The method it uses is

- (void)setBackgroundStyle:(NSBackgroundStyle)<em>style</em>

The docu says:

The default implementation automatically forwards calls to all subviews that implement setBackgroundStyle: or are an NSControl, which have NSCell classes that respond to setBackgroundStyle:.

So what you have to do is to simply implement setBackgroundStyle in your custom NSTextField. For example, save the set value to an ivar:

- (void)setBackgroundStyle:(NSBackgroundStyle)style {
_backgroundStyle = style;

Finally, use this value in your drawing code and you’re done:

- (void)drawRect:(NSRect)dirtyRect
if (self.backgroundStyle == NSBackgroundStyleDark) {
backgroundColor = [NSColor darkGrayColor];
} else {
backgroundColor = [NSColor lightGrayColor];

Leave a Reply

Your email address will not be published. Required fields are marked *