8

I am on OSX (not iOS), Xcode 8.2, Objective-C

I have two buttons with constraints. Both buttons got centered titles and both have the same width (via constraints). No when it comes to another language the buttons grows wider to fit the longer text. But i'd like to have some space between the border of the button and the text. The title insets options in IB do not exist for NSButtons and i did not find any equivalent solutions.

Any help appreciated

enter image description here

Constraints for the bottom button: ("New project" is the top button)

enter image description here

Pat_Morita
  • 3,355
  • 3
  • 25
  • 36

3 Answers3

11

You have to override intrinsicContentSize readonly property just like you would do in UILabel

Here is an example of overriding NSButton with properties that you can set their values in your xib/storyboard file via attributes inspector

//CustomButton.h file

@interface CustomButton : NSButton

@property (nonatomic, assign) IBInspectable CGFloat horizontalPadding;
@property (nonatomic, assign) IBInspectable CGFloat verticalPadding;

@end

//CustomButton.m file

@implementation CustomButton

- (NSSize) intrinsicContentSize{
    CGSize size = [super intrinsicContentSize];
    size.width += self.horizontalPadding;
    size.height += self.verticalPadding;
    return size;
}

@end

Happy coding ‍

Benny Davidovitz
  • 1,152
  • 15
  • 18
10

This is what worked for me in Swift 4

class Button: NSButton {

    @IBInspectable var horizontalPadding   : CGFloat = 0
    @IBInspectable var verticalPadding    : CGFloat = 0

    override var intrinsicContentSize: NSSize {
        var size = super.intrinsicContentSize
        size.width += self.horizontalPadding
        size.height += self.verticalPadding
        return size;
    }
}
gypsyDev
  • 1,232
  • 1
  • 14
  • 22
1

Swift 5

I made it to work for me in this way:

Set this class to your button's cell in storyboard.

class CustomNSButtonCell: NSButtonCell {

@IBInspectable var imagePaddingLeft   : CGFloat = 0
@IBInspectable var imagePaddingTop    : CGFloat = 0
@IBInspectable var textPaddingLeft   : CGFloat = 0
@IBInspectable var textPaddingTop    : CGFloat = 0

override func drawImage(_ image: NSImage, withFrame frame: NSRect, in controlView: NSView) {

    let newFrame = NSRect.init(
        origin: .init(x: frame.minX + imagePaddingLeft, y: frame.minY + imagePaddingTop),
        size: frame.size)

    super.drawImage(image, withFrame: newFrame, in: controlView)
}

override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
     let newFrame = NSRect.init(
               origin: .init(x: frame.minX + textPaddingLeft, y: frame.minY + textPaddingTop),
               size: frame.size)
    super.drawTitle(title, withFrame: newFrame, in: controlView)
    return newFrame
}

}

You can set image's left and top padding. And text's left and top padding through storyboard.

M Afham
  • 834
  • 10
  • 15