10

I have NSButtons in each row of a NSTableView.

The buttons images are set in IB and are black icons with alpha channel:

enter image description here

The windows are set to dark mode with:

window?.appearance = NSAppearance(named: NSAppearanceNameVibrantDark)

And to normal mode with:

window?.appearance = nil

The goal is that the buttons should be black when the window is white, and should be white when the window is dark, without changing when clicked.

In dark mode, in order to achieve the color change, I set the button's image "template" property to true in the NSTableCellView subclass:

public override func awakeFromNib() {
    if darkMode {
        button.image?.isTemplate = true
    } else {
        button.image?.isTemplate = false
    }
} 

The buttons are made like this in IB:

enter image description here

This works well in macOS 10.12 Sierra: when the window is white, clicking on the black button does not change its appearance and this is perfect.

But when the window is dark, clicking on the white button makes it black, which is not acceptable in my case (*). Also, the template image just doesn't work in macOS 10.11 El Capitan.

Ok:

enter image description here

Clicked, not ok:

enter image description here

And clicking again on the blackened button makes it white again...

My question is: how to force the NSButton to not highlight the template image when clicked?

I thought this was because of the "Momentary Change" type but using the other "momentary" ones doesn't change anything, and I can't set the type to "custom" either (IB refuses).

Please note that these template images behave differently in macOS 10.11 compared to macOS 10.12. The combinations of settings that work seamlessly in Sierra don't work in El Capitan. This is also why I've set a bounty: I need a solution for both systems. If there's no solution and you know why, then your explanation would also be an acceptable answer.

(*) a workaround is available on Sierra, where the template image works, by using use button.cell?.setCellAttribute(.cellLightsByContents, to: 0) to stop the button from changing color definitely when clicked (there's still a short flash though). But in El Capitan the button is black in dark mode, so this doesn't apply.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • Maybe a possible solution there: https://stackoverflow.com/questions/20064046/change-nsbuttons-background-color-on-highlight ? – Larme May 29 '17 at 15:11
  • @Larme Thanks, but unfortunately this is about the background color of regular buttons, where my question is about the buttons' template image (my buttons have no background). – Eric Aya May 29 '17 at 15:13
  • You said ‘I force the buttons to be of type "template".’ There is no button style or type named “template”. Edit your question to include a screenshot of the button's attributes in IB (if you created it in a xib or storyboard) or include the code that creates the button. – rob mayoff May 29 '17 at 17:30
  • @robmayoff Indeed it was poorly explained. I made an edit with more info. – Eric Aya May 29 '17 at 17:37
  • Are you reloading the table when you switch to dark mode? Or doing something else to change the `isTemplate` flag of your button image when you switch to dark mode? – rob mayoff May 29 '17 at 17:45
  • @robmayoff No, the app is relaunched, there's no live change of the window. I tried but I had too many issues with the tableViews and their content not being redrawn properly, so I just relaunch when the user changes the mode. Not ideal, but acceptable. // The window's NSAppearance and the buttons "template" property are the only things changing. And of course the tableView's background color to match the window (because "clear" didn't work well). – Eric Aya May 29 '17 at 17:48
  • Have you tried playing around with the `highlightsBy` or `showsStateBy` properties on `NSButtonCell`? Adjusting one or both of those as the window appearance changes might give you the results you're looking for. – kennyc May 29 '17 at 19:40
  • @kennyc Yes, on Sierra the template image works *and* I can use `button.cell?.setCellAttribute(.cellLightsByContents, to: 0)` to stop the button from changing color definitely (there's still a short flash though). But in El Capitan the button is black in dark mode, so this doesn't apply (and doesn't seem to do anything anyway). – Eric Aya May 29 '17 at 20:27
  • Switching the template-ness of the image after it's already been set on the button seems fishy. Why are you ever having it be a non-template image? Try either naming the image file to end with "Template" so it's always automatically a template image or not assigning it to the button in the NIB but programmatically *after* setting it to be a template image. You could also try setting the same image as the button's alternate image. – Ken Thomases May 29 '17 at 22:48
  • @KenThomases I had to set non-template with white windows otherwise the icons turn grey... (on both Sierra and El Capitan). // I've removed the image from IB and set it in code *before* setting `isTemplate`, but there's still the same issues in El Capitan, buttons are black in dark mode, turn white when clicked and turn black again when clicked again. – Eric Aya May 30 '17 at 17:41
  • Wait, you're setting the image on the button *before* setting `isTemplate`? That's not what I suggested. I was suggesting that you set `isTemplate` before setting the image on the button. – Ken Thomases May 30 '17 at 18:10
  • @KenThomases Oops yeah I had read that backwards. // Just did as you actually suggest and... something surprising happens (in 10.12, I don't have access to 10.11 right now for testing). In dark mode the button is black, and when I click on it this one turns white but also in all the other rows of the tableView, suddenly! After that, it works ok, but the initial state is wrong. But in white mode, the buttons are grey... and stay gray after being clicked (also with a short flash). – Eric Aya May 30 '17 at 18:38
  • 1
    Note: don't waste your time for me, in this version of this app I'm just going to use two sets of icons, a black one and a white one, and forget about the template thing. I've just tested and it solves all the issues for both OS versions. Thanks a lot for the help. :) – Eric Aya May 30 '17 at 19:31
  • However, of course, I'm still very curious about all this. If someone wants to explain these differences between 10.11 and 10.12 regarding image templates, and where to init templates if not in the awakeFromNib of the NSTableCellView subclass, and are the issues related to the icons being in a tableView, and why buttons behave differently with and without NSAppearance, this could be an interesting answer. – Eric Aya May 30 '17 at 19:32
  • 1
    @Moritz Hey, honestlly I played around with it previously - and this template thingy never worked as expected :-(, every time I've hit the issue I just ended up putting 2 sets of images for bright and dark mode - I think prior to El Capitan it worked ok, but in El Capitan got completely broken - worth firing a bug radar for Apple. – Coldsteel48 Oct 13 '17 at 01:29

0 Answers0