Search code examples
swiftmacosbuttonnsbuttonnsbuttoncell

NSButton in Swift, handle click and release events


i'm trying to manage different state of a simple push button on an OS X application : When the user click on it, and when the user release the click.

Currently i set my button type by NSMomentaryLightButton

NSMomentaryLightButton When the button is clicked (on state), it appears illuminated. If the button has borders, it may also appear recessed. When the button is released, it returns to its normal (off) state.

This type of button is best for simply triggering actions because it doesn’t show its state; it always displays its normal image or title. This option is called Momentary Light in Interface Builder’s Button inspector

I thought it was the good way, but when i print my button status, it's like a toggle button than the push button that i set. As you can see on exemple gif

To sum up, How can i have a real push button behaviour ? Call function when the user click on it, and when the user release the click.

Thank,


Solution

  • You don't want to use buttons for piano keys. First, they are non-rectangular, and they don't act as buttons do: neither single-action push-button, nor toggle switches. You are interacting in a custom way, with a custom view, meaning the NSButton control hierarchy isn't called for. Instead you're subclassing NSView and capturing low-level mouse events as detailed here:

    https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html#//apple_ref/doc/uid/10000060i-CH6-SW1

    You found this yourself as you detailed in your own comments, but I wanted to make sure you had a higher level point of view. It's even possible, and probably best, to consolidate all of the piano keys into a single view, and let the keys themselves be rendered using NSBezierPath and perform mouse hit detection using containsPoint:

    https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSBezierPath_Class/#//apple_ref/occ/instm/NSBezierPath/containsPoint:

    This is a lot more work but the only way to make a truly professional looking piano simulation. Then you can render the keys with whatever outline, fill, and labeling you need without the limitations of built-in button shapes and layout. You could even have the bottom edges of the keys slightly rounded, for example, or apply a shiny texture.