Search code examples
macoscocoacustom-controlsnsbuttonnsbuttoncell

Custom NSButton drawing messes up text rendering


I'm subclassing NSButton / NSButtonCell and everything works fine, but at least in Retina drawing as soon as I implement any of the drawing functions in either NSButton or NSButtonCell, the text rendering changes no matter whether I do some custom text drawing or delegate straight to the super implementation.

button drawing

As you can see the text goes much thinner with just the anti-aliasing changing.

When I examine this in Xcode's Reveal-rip off, I see that the text is embedded in a NSButtonTextField when none of the drawing methods are overridden. As soon as any of the drawing methods are overridden, the NSButtonTextField disappears.

None of this happens when I insert a background layer behind the button text and set

button.isBorderd = false

but I don't much like that solution.

Is there any way of getting the same "fat" text rendering without messing with layers? Perhaps an attributed string attribute, a special text drawing command, anything?

Any help would be appreciated/


Solution

  • I wasn't able to reproduce your work-around with a background layer, though I might've been doing it wrong.

    I ended up adding an NSTextField as a subview to the button, with the following attributes:

    _titleTextField = [[NSTextField alloc] initWithFrame:NSZeroRect];
    [_titleTextField setBordered:NO];
    [_titleTextField setDrawsBackground:NO];
    [_titleTextField setFont:[NSFont systemFontOfSize:13]];
    [_titleTextField setTextColor:[FantasticalColors color:@"dimLabelTextColor"]];
    [_titleTextField setStringValue:[self title]];
    [_titleTextField setEditable:NO];
    [_titleTextField setFocusRingType:NSFocusRingTypeNone];
    [self addSubview:_titleTextField];
    

    Then I was able to render all non-text in my cell's drawRect, and then let the text field render the text. Also not ideal, but was the only way I was able to match font rendering.