Josh Kahane
Josh Kahane

Reputation: 17169

How Can I Change NSButton Color?

I have been using the setBackgroundColor method to change the NSButton colour, but my question is, are there any other methods I could use to change the colour of an NSButton other than that?

Upvotes: 2

Views: 4909

Answers (2)

paxos
paxos

Reputation: 927

I don't know what is going on here, but the following works for me:

[[myButton cell] setBackgroundColor:[NSColor redColor]];

But ONLY if I overwrite the following method in my NSButtonCell subclass:

- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView
{
    [super drawBezelWithFrame:frame inView:controlView];
}

Fun fact here: it is not even called (tested with debugger).

Upvotes: 1

Anoop Vaidya
Anoop Vaidya

Reputation: 46563

To change the color or the NSButton you need to access the button, mostly you do it with IBOutlet unless the buttons are in TableView / CollectionView etc.

Say the button outlet is myButton, then you need

[[myButton cell] setBackgroundColor:[NSColor redColor]]; //Change the color according to your need

Edit:

You can also do this by subclassing NSButtonCell with these methods

- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView
{
    NSGraphicsContext* ctx = [NSGraphicsContext currentContext];

    // corner radius
    CGFloat roundedRadius = 17.0f;

    NSColor *color = [NSColor redColor];

    // Draw darker overlay if button is pressed
    if([self isHighlighted]) {
        [ctx saveGraphicsState];
        [[NSBezierPath bezierPathWithRoundedRect:frame
                                         xRadius:roundedRadius
                                         yRadius:roundedRadius] setClip];
        [[color darkenColorByValue:0.12f] setFill];
        NSRectFillUsingOperation(frame, NSCompositeSourceOver);
        [ctx restoreGraphicsState];

        return;
    }

    // create background color
    [ctx saveGraphicsState];
    [[NSBezierPath bezierPathWithRoundedRect:frame
                                     xRadius:roundedRadius
                                     yRadius:roundedRadius] setClip];
    [[color darkenColorByValue:0.12f] setFill];
    NSRectFillUsingOperation(frame, NSCompositeSourceOver);
    [ctx restoreGraphicsState];


    //draw inner button area
    [ctx saveGraphicsState];

    NSBezierPath* bgPath = [NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1.0f, 1.0f) xRadius:roundedRadius yRadius:roundedRadius];
    [bgPath setClip];

    NSColor* topColor = [color lightenColorByValue:0.12f];

    // gradient for inner portion of button
    NSGradient* bgGradient = [[NSGradient alloc] initWithColorsAndLocations:
                              topColor, 0.0f,
                              color, 1.0f,
                              nil];
    [bgGradient drawInRect:[bgPath bounds] angle:90.0f];

    [ctx restoreGraphicsState];
}

- (NSRect) drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView {
    NSGraphicsContext* ctx = [NSGraphicsContext currentContext];

    [ctx saveGraphicsState];
    NSMutableAttributedString *attrString = [title mutableCopy];
    [attrString beginEditing];

    NSColor *titleColor;
    if ([[self getColorForButtonType] isLightColor]) {
        titleColor = [NSColor blackColor];
    } else {
        titleColor = [NSColor whiteColor];
    }

    [attrString addAttribute:NSForegroundColorAttributeName value:titleColor range:NSMakeRange(0, [[self title] length])];
    [attrString endEditing];
    NSRect r = [super drawTitle:attrString withFrame:frame inView:controlView];

    [ctx restoreGraphicsState];

    return r;
}

Upvotes: 1

Related Questions