5

I'm trying to subclass NSCell to draw a custom background highlight. The documentation seems to suggest that the overriding highlight:withFrame:inView: should allow me to do this but the method is never called.

Instead, I've overridden drawInteriorWithFrame:inView: which works fine - I can draw what I want in the cell. However, the issue is that I have to draw everything myself, losing the functionality of the type of NSCell I am extending - for example an NSTextFieldCell's ability to display text:

Custom drawn highlighted cell:

enter image description here

However, I just want to redraw the background (the highlight), and retain the ability to use the main functionality of the extended cell:

enter image description here

I could, of course, just draw the text myself too but I'm hoping there is an easier way of doing this.

Any help is much appreciated.

JoeR
  • 1,901
  • 3
  • 25
  • 39
  • 2
    Are you sending `[super drawInteriorWithFrame:cellFrame inView:controlView];` (with whatever parameter names you’re using) after you’ve drawn your custom background? –  Feb 18 '11 at 12:44
  • @Bavarious - If I do that then the custom background is lost. Result is the same as the second screenshot as I'd presume that method draws its own background too. – JoeR Feb 18 '11 at 12:47
  • 2
    Ah, gotcha. Can’t you set a transparent highlight colour so that `super` won’t mess with your custom highlight, and then you use `-isHighlighted` inside `-drawInterior…` to decide how you should draw the background? –  Feb 18 '11 at 12:51
  • @Bavarious - Interesting idea. Returning [NSColor clearColor] for `highlightColorWithFrame:inView:` just showed through to the desktop like http://i.imgur.com/jy970.png. However, returning nil for the same method did what I wanted - http://i.imgur.com/joUom.png - thanks for your help! – JoeR Feb 18 '11 at 12:57
  • Cheers! May I suggest you describe what you’ve done as an answer and accept it? –  Feb 18 '11 at 12:59

1 Answers1

11

Thanks to the help of @Bavarious I've managed to work it out. My extended NSTextFieldCell class implementation now contains:

-(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    return nil;
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    if ([self isHighlighted]) {
        // Draw highlight background here
    }

    [super drawInteriorWithFrame:cellFrame inView:controlView];
}

The key is to make sure you return nil for highlightColorWithFrame:inView: to stop drawInteriorWithFrame:inView: drawing a background and yet still calling it to draw the main content (in this case text).

JoeR
  • 1,901
  • 3
  • 25
  • 39
  • How **exactly** you draw background ? I only can change the text color. I have used ... ` if( [self isHighlighted] ) { NSColor *oldColor = [self backgroundColor]; [self setBackgroundColor:[NSColor whiteColor]]; [super drawWithFrame:cellFrame inView:controlView]; [self setBackgroundColor:oldColor]; } ` but nothing happens! Thanks... – Vassilis Feb 27 '11 at 23:49
  • Have you actually overridden `-drawInteriorWithFrame:inView:` rather than `-drawWithFrame:inView:`? – UncleAli Jun 11 '13 at 09:08
  • How do you do this with Swift? It's not possible to return nil from highlightColorWithFrame!!!! – ioquatix Oct 14 '16 at 01:04