3

How to modify look and feel of NSButton, I want to create a toggle button which looks similar to NSRoundRectBezelStyle but with Image and custom height

How do i change background color, color change on hover, change color on click, create toggle effect when state is ON or OFF, create border which is similar to NSRoundRectBezelStyle. Existing native button doesn't have exact UI as that of my UI Element.

UI should look something like below, but I want to add Image above text also.

enter image description here

This Mac Button - Hover effect

Desktop Button - Toggle ON effect

Shared Button - Toggle OFF effect

Sahil Doshi
  • 1,073
  • 10
  • 23
  • If the native `NSButton` can't do what you want, you have to create a subclass of `NSButton` and/or `NSButtonCell`. Read [Button Programming Topics](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Button/Button.html#//apple_ref/doc/uid/10000019-BAJFBADA). Is an icon checkbox what you want? – Willeke Jul 25 '17 at 09:37
  • Yes, but documentation doesn't have enough explanation of implementation. Kindly provide some link which have some detailed information on implementation. And i don't want check box, i want toggle button, push on push off type of button. – Sahil Doshi Jul 26 '17 at 04:20
  • From [Using Checkboxes](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Button/Concepts/CheckBoxes.html#//apple_ref/doc/uid/20000251-BCIBFHAA): "**Icon Checkboxes** You can also have a checkbox that’s an icon button; that is, one that’s primarily identified by its icon and has little or no text. If the button’s off, it appears to be sticking out. If the button’s on, it appears to be pressed in. (An icon button cannot display the mixed state.) – Willeke Jul 26 '17 at 07:53
  • 1
    You can create an icon checkbox in either Interface Builder or programmatically. If you use Interface Builder, start with a push button. If you create it programmatically, create an instance of NSButton. Then change it by setting its type to NSPushOnPushOffButton, its image position to NSImageOnly, its bezel type to a square bezel type. Then set the image to what you want.". Give it a try. – Willeke Jul 26 '17 at 07:53
  • 1
    Hover: [NSButton: show alternate image on hover](https://stackoverflow.com/questions/19859782/nsbutton-show-alternate-image-on-hover). Instead of the alternate image, draw an alternate background. – Willeke Jul 26 '17 at 07:55

2 Answers2

1

I think it's just this:

let button = NSButton(title: "Title", target: self, action: #selector(doSomething(_:)))
button.setButtonType(.pushOnPushOff)
button.bezelStyle = NSButton.BezelStyle.recessed
// the magic line
button.showsBorderOnlyWhileMouseInside = true
Mark Bridges
  • 8,228
  • 4
  • 50
  • 65
1

You can achieve this by creating a NSButton with the following attributes:

Style: "Push"; Type: "Push On Push Off"; Bordered: "Yes"

And subclassing NSButton and overriding few of its methods.

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if(self)
    {
        self.showsBorderOnlyWhileMouseInside = YES;
    }
    return self;
}

- (void)setState:(NSControlStateValue)state
{
    if(state == NSControlStateValueOn)
    {
        self.showsBorderOnlyWhileMouseInside = NO;
    }
    else
    {
        self.showsBorderOnlyWhileMouseInside = YES;
    }
}

This will yield a result as such:

Toggle OFF effect

enter image description here

Hover effect

enter image description here

Toggle ON effect

enter image description here

Happy Coding!!!