on OSX I have an NSButton with a pretty dark image and unfortunately it is not possible to change the color using the attributes inspector. See picture the big black button,
My solution:
.h
IB_DESIGNABLE
@interface DVButton : NSButton
@property (nonatomic, strong) IBInspectable NSColor *BGColor;
@property (nonatomic, strong) IBInspectable NSColor *TextColor;
@end
.m
@implementation DVButton
- (void)awakeFromNib
{
if (self.TextColor)
{
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setAlignment:NSCenterTextAlignment];
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
self.TextColor, NSForegroundColorAttributeName,
self.font, NSFontAttributeName,
style, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:self.title attributes:attrsDictionary];
[self setAttributedTitle:attrString];
}
}
- (void)drawRect:(NSRect)dirtyRect
{
if (self.BGColor)
{
// add a background colour
[self.BGColor setFill];
NSRectFill(dirtyRect);
}
[super drawRect:dirtyRect];
}
@end
And here’s a Swift 3 version:
import Cocoa
@IBDesignable
class DVButton: NSButton
{
@IBInspectable var bgColor: NSColor?
@IBInspectable var textColor: NSColor?
override func awakeFromNib()
{
if let textColor = textColor, let font = font
{
let style = NSMutableParagraphStyle()
style.alignment = .center
let attributes =
[
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: font,
NSParagraphStyleAttributeName: style
] as [String : Any]
let attributedTitle = NSAttributedString(string: title, attributes: attributes)
self.attributedTitle = attributedTitle
}
}
override func draw(_ dirtyRect: NSRect)
{
if let bgColor = bgColor
{
bgColor.setFill()
NSRectFill(dirtyRect)
}
super.draw(dirtyRect)
}
}
and Swift 4.0 version:
import Cocoa
@IBDesignable
class Button: NSButton
{
@IBInspectable var bgColor: NSColor?
@IBInspectable var textColor: NSColor?
override func awakeFromNib()
{
if let textColor = textColor, let font = font
{
let style = NSMutableParagraphStyle()
style.alignment = .center
let attributes =
[
NSAttributedStringKey.foregroundColor: textColor,
NSAttributedStringKey.font: font,
NSAttributedStringKey.paragraphStyle: style
] as [NSAttributedStringKey : Any]
let attributedTitle = NSAttributedString(string: title, attributes: attributes)
self.attributedTitle = attributedTitle
}
}
override func draw(_ dirtyRect: NSRect)
{
if let bgColor = bgColor
{
bgColor.setFill()
__NSRectFill(dirtyRect)
}
super.draw(dirtyRect)
}
}
Swift 4.2 version of David Boyd's solution
extension NSButton {
func setAttributes(foreground: NSColor? = nil, fontSize: CGFloat = -1.0, alignment: NSTextAlignment? = nil) {
var attributes: [NSAttributedString.Key: Any] = [:]
if let foreground = foreground {
attributes[NSAttributedString.Key.foregroundColor] = foreground
}
if fontSize != -1 {
attributes[NSAttributedString.Key.font] = NSFont.systemFont(ofSize: fontSize)
}
if let alignment = alignment {
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = alignment
attributes[NSAttributedString.Key.paragraphStyle] = paragraph
}
let attributed = NSAttributedString(string: self.title, attributes: attributes)
self.attributedTitle = attributed
}
}
I've created a NSButton
subclass called FlatButton
that makes it super-easy to change the text color in the Attributes Inspector of Interface Builder like you are asking for. It should provide a simple and extensive solution to your problem.
It also exposes other relevant styling attributes such as color and shape.
You'll find it here: https://github.com/OskarGroth/FlatButton
This is how I get it done in Swift 4
@IBOutlet weak var myButton: NSButton!
// create the attributed string
let myString = "My Button Title"
let myAttribute = [ NSAttributedStringKey.foregroundColor: NSColor.blue ]
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute)
// assign it to the button
myButton.attributedTitle = myAttrString
NSColor color = NSColor.White;
NSMutableAttributedString colorTitle = new NSMutableAttributedString (cb.Cell.Title);
NSRange titleRange = new NSRange (0, (nint)cb.Cell.Title.Length);
colorTitle.AddAttribute (NSStringAttributeKey.ForegroundColor, color, titleRange);
cb.Cell.AttributedTitle = colorTitle;
Using the info above, I wrote a NSButton extension that sets the foreground color, along with the system font and text alignment.
This is for Cocoa on Swift 4.x, but could be easily adjusted for iOS.
import Cocoa
extension NSButton {
func setAttributes(foreground: NSColor? = nil, fontSize: CGFloat = -1.0, alignment: NSTextAlignment? = nil) {
var attributes: [NSAttributedStringKey: Any] = [:]
if let foreground = foreground {
attributes[NSAttributedStringKey.foregroundColor] = foreground
}
if fontSize != -1 {
attributes[NSAttributedStringKey.font] = NSFont.systemFont(ofSize: fontSize)
}
if let alignment = alignment {
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = alignment
attributes[NSAttributedStringKey.paragraphStyle] = paragraph
}
let attributed = NSAttributedString(string: self.title, attributes: attributes)
self.attributedTitle = attributed
}
}