Wrap NSButton title
Even later, but I also feel obliged to share. You can set the attributedTitle property of NSButton to achieve manual wrapping.
In my case, I wanted the button title to wrap if it was greater than 6 characters (Swift 3):
if button.title.characters.count > 6 {
var wrappedTitle = button.title
wrappedTitle.insert("\n", at: wrappedTitle.index(wrappedTitle.startIndex, offsetBy: 6))
let style = NSMutableParagraphStyle()
style.alignment = .center
let attributes = [NSFontAttributeName: NSFont.systemFont(ofSize: 19), NSParagraphStyleAttributeName: style] as [String : Any]
button.attributedTitle = NSAttributedString(string: wrappedTitle, attributes: attributes)
}
I don't believe you can. You'd have to subclass NSButtonCell
to add support for this.
That said, it's typically a bad idea to have multiple lines of text on a button. A button label should concisely represent the action performed:
The label on a push button should be a verb or verb phrase that describes the action it performs—Save, Close, Print, Delete, Change Password, and so on. If a push button acts on a single setting, label the button as specifically as possible; “Choose Picture…,” for example, is more helpful than “Choose…” Because buttons initiate an immediate action, it shouldn’t be necessary to use “now” (Scan Now, for example) in the label.
What are you trying to do?
Well here's my excuse for needing multiline buttons: I'm writing an emulator for an IBM 701, complete with front panel, and, bless their hearts, the designers of that front panel used multi-line labels. Here's my code. You only have to subclass NSButtonCell (not NSButton), and only one method needs to be overridden.
// In Xcode 4.6 (don't know about earlier versions): Place NSButton, then double-click it
// and change class NSButtonCell to ButtonMultiLineCell.
@interface ButtonMultiLineCell : NSButtonCell
@end
@implementation ButtonMultiLineCell
- (NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView
{
NSAttributedString *as = [[NSAttributedString alloc] initWithString:[title.string stringByReplacingOccurrencesOfString:@" " withString:@"\n"]];
NSFont *sysFont = [NSFont systemFontOfSize:10];
NSMutableParagraphStyle *paragraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[paragraphStyle setAlignment:NSCenterTextAlignment];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
sysFont, NSFontAttributeName,
paragraphStyle, NSParagraphStyleAttributeName,
nil];
NSSize textSize = [as.string sizeWithAttributes:attributes];
NSRect textBounds = NSMakeRect(0, 0, textSize.width, textSize.height);
// using frame argument seems to produce text in wrong place
NSRect f = NSMakeRect(0, (controlView.frame.size.height - textSize.height) / 2, controlView.frame.size.width, textSize.height);
[as.string drawInRect:f withAttributes:attributes];
return textBounds; // not sure what rectangle to return or what is done with it
}
@end
I`m incredibly late, but I still feel obliged to share what I`ve found.
Just add a newline character before and after the button title before you assign it to the actual button — and voilà! It now wraps automatically.
The downside of this approach is that, for reasons unknown to me, apps compiled on a certain version of OS X shift button titles one line down when run on newer versions.