Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSButton with round corners and background color

Tags:

macos

swift

I want a simple push button (the one with the round corners), and to add background to it. I've tried 2 things:

1 - using a round button image: this is working good, until I need to scale the button, which cause the round parts to look ugly.

2 - extending the button and add color to it - but then I have trouble when I click the button - I want the "pushed" state to be at the same color as the "regular" state, but it's not the case.

this is the code I'm using to extend the button:

 override func drawRect(dirtyRect: NSRect)
    {
        if let bgColor = bgColor {
            self.layer?.cornerRadius = 4
            self.layer?.masksToBounds = true
            self.layer?.backgroundColor = bgColor.CGColor
            bgColor.setFill()

            NSRectFill(dirtyRect)
        }

        super.drawRect(dirtyRect)
    }

Anyway, neither approach 1 nor 2 worked, so how can I achieve this ? Just a simple button.. :(

EDIT: I'm asking about OSX

like image 345
Roee84 Avatar asked Sep 14 '16 11:09

Roee84


People also ask

How do I change the background color in NSButton?

m file [[myButton cell] setBackgroundColor:[NSColor redColor]]; Note from the setBackgroundColor documentation: "The background color is used only when drawing borderless buttons." If this won't do it for you then you'll need to override NSButton and implement the drawing yourself.

How do I change the background color of a button in swift 5?

Method 1 − Using the storyboard editorAdd a button on your storyboard, select it Go to it's attribute inspector and select 'Background' property to choose the color.

How do I change the background color in Swift?

Find the view or view controller you want to change the background color of. Open it up in the interface builder and open the Attributes Inspector. Find the background color field and set it to the color you want.


1 Answers

OBJECTIVE-C solution (might help some guys stumble upon this thread)

This sublass extends IB - so you can IB control either:

  • Background Color
  • Background Color on Hover
  • Title Color
  • Title Color on Hover
  • Corner Radius

It also includes a little alpha animation on hover.

New controls in IB (click to see screenshot)

//
//  SHFlatButton.h
//
//  Created by SH on 03.12.16.
//  Copyright © 2016 SH. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface SHFlatButton : NSButton

@property (nonatomic, strong) IBInspectable NSColor *BGColor;
@property (nonatomic, strong) IBInspectable NSColor *TextColor;
@property (nonatomic, strong) IBInspectable NSColor *BGColorHover;
@property (nonatomic, strong) IBInspectable NSColor *TextColorHover;
@property (nonatomic) IBInspectable CGFloat CornerRadius;
@property (strong) NSCursor *cursor;

@end

And the implementation...

//
//  SHFlatButton.m
//
//  Created by SH on 03.12.16.
//  Copyright © 2016 SH. All rights reserved.
//

#import "SHFlatButton.h"

@implementation SHFlatButton

- (void)awakeFromNib
{
    if (self.TextColor)
        [self setAttributedTitle:[self textColor:self.TextColor]];

    if (self.CornerRadius)
    {
        [self setWantsLayer:YES];
        self.layer.masksToBounds = TRUE;
        self.layer.cornerRadius = self.CornerRadius;
    }
}


- (void)drawRect:(NSRect)dirtyRect
{
    if (self.BGColor)
    {
        [self.BGColor setFill];
        NSRectFill(dirtyRect);
    }

    [super drawRect:dirtyRect];
}


- (void)resetCursorRects
{
    if (self.cursor) {
        [self addCursorRect:[self bounds] cursor: self.cursor];
    } else {
        [super resetCursorRects];
    }
}


- (void)updateTrackingAreas {

    NSTrackingArea* trackingArea = [[NSTrackingArea alloc]
                                    initWithRect:[self bounds]
                                    options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
                                    owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}


- (void)mouseEntered:(NSEvent *)theEvent{
    if ([self isEnabled]) {

        [[self animator]setAlphaValue:0.9];
        if (self.BGColorHover)
            [[self cell] setBackgroundColor:self.BGColorHover];
        if (self.TextColorHover)
            [self setAttributedTitle:[self textColor:self.TextColorHover]];
    }


}

- (void)mouseExited:(NSEvent *)theEvent{
    if ([self isEnabled]) {
        [[self animator]setAlphaValue:1];
        if (self.BGColor)
            [[self cell] setBackgroundColor:self.BGColor];
        if (self.TextColor)
            [self setAttributedTitle:[self textColor:self.TextColor]];
    }
}

- (NSAttributedString*)textColor:(NSColor*)color
{
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setAlignment:NSCenterTextAlignment];
    NSDictionary *attrsDictionary  = [NSDictionary dictionaryWithObjectsAndKeys:
                                      color, NSForegroundColorAttributeName,
                                      self.font, NSFontAttributeName,
                                      style, NSParagraphStyleAttributeName, nil];
    NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:self.title attributes:attrsDictionary];
    return attrString;
}

EDIT: Button MUST have border disabled!

like image 197
Pat_Morita Avatar answered Oct 13 '22 02:10

Pat_Morita