1
votes

I have a custom NSButton, but no matter what i do, the disabled color is always gray

I tried all solutions i came across

  • i'am setting the attributed string title with white foreground color (i looks like the color attribute is ignored for the disabled state)

  • i did set [[self cell] setImageDimsWhenDisabled:NO];

event when the documentations states

// When disabled, the image and text of an NSButtonCell are normally dimmed with gray.
// Radio buttons and switches use (imageDimsWhenDisabled == NO) so only their text is dimmed.
@property BOOL imageDimsWhenDisabled;

it doesn't work

My NSButton uses wantsUpdateLayer YES, so the draw methods are overwritten, but i don't understand, where the title is drawn

2

2 Answers

4
votes

On OS X 10.9 I've managed to alter the color of the button's text when it's disabled by sub-classing the cell that draws the button.

Create a new NSButtonCell subclass in Xcode and override the following method:

- (NSRect)drawTitle:(NSAttributedString *)title
      withFrame:(NSRect)frame
         inView:(NSView *)controlView {

    NSDictionary *attributes = [title attributesAtIndex:0 effectiveRange:nil];

    NSColor *systemDisabled = [NSColor colorWithCatalogName:@"System" 
                                                  colorName:@"disabledControlTextColor"];
    NSColor *buttonTextColor = attributes[NSForegroundColorAttributeName];

    if (systemDisabled == buttonTextColor) {
        NSMutableDictionary *newAttrs = [attributes mutableCopy];
        newAttrs[NSForegroundColorAttributeName] = [NSColor orangeColor];
        title = [[NSAttributedString alloc] initWithString:title.string
                                            attributes:newAttrs];
    }

     return [super drawTitle:title
              withFrame:frame
                 inView:controlView];

}

Select the button in Xcode, then select its cell (maybe easiest to do this in the Interface Builder dock), now got to the Identity Inspector and set the cell's class to that of your subclass.

0
votes

This is because of the default true value of

- (BOOL)_shouldDrawTextWithDisabledAppearance

Try to change this method instead of imageDimsWhenDisabled. If you are using Swift 4, I would do the following in the Bridging header:

#import <AppKit/AppKit.h>
@interface NSButtonCell (Private)
- (BOOL)_shouldDrawTextWithDisabledAppearance;
@end

And in the subclass of NSButtonCell:

override func _shouldDrawTextWithDisabledAppearance() -> Bool {
    return false
}

And that's it: the grey should disappear