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, un
Here's what works for me (Swift 4).
To set background color:
myButton.layer?.backgroundColor = CGColor.customSilver
To set corner radius:
myButton.layer?.cornerRadius = 3
Override NSButtonCell's drawWithFrame method:
func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
var border = NSBezierPath(roundedRect: NSInsetRect(cellFrame, 0.5, 0.5), xRadius: 3, yRadius: 3)
NSColor.greenColor().set()
border.fill()
var style = NSParagraphStyle.defaultParagraphStyle()
style.alignment = NSCenterTextAlignment
var attr = [NSParagraphStyleAttributeName : style, NSForegroundColorAttributeName : NSColor.whiteColor()]
self.title.drawInRect(cellFrame, withAttributes: attr)
}
Simple 3 line function.
@IBOutlet weak var button: UIButton!
func setButton(color: UIColor, title: String) {
button.backgroundColor = color
button.setTitle(title, forState: .Normal)
button.layer.cornerRadius = 8.0
}
and call it like such
setButton(UIColor.redColor(), title: "Hello")
OBJECTIVE-C solution (might help some guys stumble upon this thread)
This sublass extends IB - so you can IB control either:
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!
You need to override function layoutSubviews,i.e.
override func layoutSubviews() {
self.layer.cornerRadius = self.frame.height/2
self.layer.borderColor = UIColor.blue.cgColor
self.layer.borderWidth = 2
}
I have committed a sample project here. All your related code has been written in button.swift and it is in swift 3. Also, I have not set the background image for the button, I am leaving that task up to you.
P.S.: The answer below is for UIButton, not NSButton. Probably some of it will be valid, probably not everything...
I made a button and succeeded. It looks like this:
Code:
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
if let bgColor = bgColor {
self.layer?.cornerRadius = 4
self.layer?.masksToBounds = true
self.layer?.backgroundColor = bgColor.cgColor
bgColor.setFill()
NSRectFill(dirtyRect)
}
}
drawRect is replaced by draw, and CGColor is replaced by cgColor. The difference between yours and mine is the order. You called super.draw(dirtyRect)
as last, and I called it first. Maybe your button looks like this:
I hope this can solve your problem.