8

When creating Cocoa bevel button with custom image and alternate image I'm having a strange behavior. In the pressed state the button background becomes white. I'm adding the button as subview of a transparent window (HUD window).

I'm trying every technique that I know:

NSButton *closeButton = [[NSButton alloc] initWithFrame:NSMakeRect(0.0, 0.0, 30.0, 30.0)];
        [closeButton setFrameOrigin:NSMakePoint(0.0, 0.0)];
        [closeButton setImagePosition:NSImageOnly];
        [closeButton setAction:@selector(closeWindowAction:)];
        [closeButton setBordered:NO];
        [closeButton setTransparent:NO];

        [closeButton setImage:[NSImage imageNamed:@"icon-tclose-off"]];
        [closeButton setAlternateImage:[NSImage imageNamed:@"icon-tclose-on"]];
        [closeButton setBezelStyle:NSShadowlessSquareBezelStyle];
        [closeButton setButtonType:NSMomentaryLightButton];

        //[[closeButton cell] setBackgroundColor:[NSColor clearColor]];
        [[closeButton cell] setHighlightsBy:NSChangeBackgroundCellMask|NSCellLightsByContents];
        //[[closeButton cell] setHighlightsBy:NSContentsCellMask];
        //[[closeButton cell] setShowsStateBy:0|NSContentsCellMask];

I also tried

[closeButton setButtonType:NSMomentaryChangeButton];

[[closeButton cell] setHighlightsBy:NSContentsCellMask];

with no results.

You can see the wrong behavior in the attached screenshots:

Bevel button overlaying a HUD window:
Bevel button overlaying a HUD window

Wrong bevel button background:
Wrong Bevel button background

Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
loretoparisi
  • 15,724
  • 11
  • 102
  • 146

4 Answers4

25

Depending on your situation, this may also work:

Change the style of the button to Bevel or Square, the mode should be set to "Momentary Change" and Border, Transparent, Mixed and Selected should be OFF. This is how I fixed the white background problem on my buttons.

Ryan
  • 1,435
  • 13
  • 16
4

I have made it work by setting cell.highlightsBy to ContentsCellMask:

let btn = NSButton(frame: myFrame)

btn.image = myButtonImage
btn.image?.size = myFrame.size
btn.imagePosition = .ImageOnly

btn.bordered = false      
(btn.cell as? NSButtonCell)?.highlightsBy = .ContentsCellMask

view.addSubview(btn)

This way the button is darkened when pressed, but no ugly square appears. Tested only in El Capitan).

Georgy Pashkov
  • 1,285
  • 7
  • 11
2

Creating button

NSButton *myButton;
myButton = [[NSButton new] autorelease];
[myButton setTitle: @"Hello!"];
[myButton sizeToFit];
[myButton setTarget: self];
[myButton setAction: @selector (function:)];

Add button to window

unsigned int styleMask = NSTitledWindowMask 
                           | NSMiniaturizableWindowMask;
NSWindow *myWindow;
myWindow = [NSWindow alloc];
/*get the size of the button*/
NSSize buttonSize;
buttonSize = [myButton frame].size;
/*set window content rect with the size of the button, and with an origin of our choice; (100, 100)*/
NSRect rect;
rect = NSMakeRect (100, 100, 
                   buttonSize.width, 
                   buttonSize.height);

myWindow = [myWindow initWithContentRect: rect
                       styleMask: styleMask
                       backing: NSBackingStoreBuffered
                       defer: NO];
[myWindow setTitle: @"my window"];
/*replacing the default window content view with our button*/
[myWindow setContentView: myButton];
Parag Bafna
  • 22,812
  • 8
  • 71
  • 144
  • It's not clear to me which is this NSWindow myWindow. Is it the button container? In this case its content rect is what you defined as NSRect rect? – loretoparisi Oct 13 '11 at 22:44
  • I tried this solution and replacing the contentView of a window fixes the problem of the white background of a NSButton, but it introduces another problem, the key window focus. This happens in one case: when clicking on the close button but not releasing it (so performing just a button press event). In that case the NSWindow handling the button gains focus, and the window below (and the other windows will loose focus. So the problem is that the user has to click twice on another window (the HUD in my case) before getting the focus. – loretoparisi Oct 16 '11 at 14:59
1

You should set button type: myButton.buttonType = NSMomentaryChangeButton;