Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSButton text insets with autolayout constraints

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

like image 428
Pat_Morita Avatar asked Apr 18 '17 15:04

Pat_Morita


3 Answers

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 👨‍💻

like image 149
Benny Davidovitz Avatar answered Nov 04 '22 08:11

Benny Davidovitz


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;
    }
}
like image 34
gypsyDev Avatar answered Nov 04 '22 07:11

gypsyDev


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.

like image 1
M Afham Avatar answered Nov 04 '22 07:11

M Afham