Opt-out borderless NSButton from NSVisualEffectView vibrancy - macos

I have a NSVisualEffectView with vibrancy containing text fields (NSTextField or NSComboBox) and borderless buttons. The buttons are positioned over the text fields and I want to disable the vibrancy effect on the borderless buttons since they're supposed to appear on the white background of the text fields.
What I tried doing, as per recommendation in the NSVisualEffectView class reference, is to wrap my NSButton inside another NSVisualEffectView with its state set to Inactive. What this does is it replaces the "vibrant" background by a light grey background.
The picture below illustrates this. The first field is my attempted solution, the second shows the default behavior of a borderless button as child of a NSVisualEffectView.
I also tried subclassing the NSButton and set its cell background color to white or clear but I always get the grey background.
How can I change the light grey background to a white or clear background?
Thanks

I managed to solve this myself after a few hours of headache. The solution doesn't need the button to be wrapped in a NSVisualEffectView. Simply subclassing NSButton and overriding the allowsVibrancy property and setting it to false was enough.
In Swift:
override var allowsVibrancy: Bool { return false }

Related

How to mimic the item highlight behavior of NSTableView in NSCollectionView?

I have NSCollectionView with custom items which contain NSTextField and NSImageView.
I realized highlight behavior of collection view items manually (ie. redefined the setSelected: method in my NSCollectionViewItem descendant class).
I successfully change the background color of selected items, but I miss one small but important thing: the text color of the selected item doesn't change.
I know that the NSTableView item highlighting changes the text color along with the background color, but I cannot mimic it since I don't know the algorithm of color's change.
The text color of my NSCollectionViewItems can be different. When I highlight the item in NSTableView, the gray text becomes lightgray, black becomes white and so on.
Does anybody know how they do that? Maybe there's a ready solution in the Cocoa API that I missed? Please help.

How to set color for a button in Xcode7?

Hi Im new to Xcode7 and Swift2 and I am trying to change the color of the buttons I am adding to my storyboard. Is there a way to change the color of the button in Xcode7? All I see are options to change color of text and add background image to a button but no change button color.
A button has many parts / aspects, so what do you mean by the "button color"? You probably mean the button's background color. If you scroll down in the button's attributes inspector, you'll come to the background color. The reason it's so far down is that it's a View (UIView) property, not merely a button (UIButton) property.

Unexpected NSTextField background color, should be transparent

UPDATE:
I've added a sample project for testing, see at the bottom of the post.
ORIGINAL QUESTION:
I've got an NSWindow and I change its background when some other parameters change.
The window background is a gradient I'm drawing by overriding drawRect in a subclass of the window's view.
class MainWindowView: NSView {
override func drawRect(dirtyRect: NSRect) {
var rect = dirtyRect
let gradient = NSGradient(startingColor: backgroundColor, endingColor: darkerBackgroundColor)
gradient.drawInRect(rect, relativeCenterPosition: NSPoint(x: 0, y: 0))
super.drawRect(rect)
}
}
And I've got two NSTextFields on this window.
The NSTextFields are both set to drawsBackground = false in awakeFromNib and set to borderless in IB.
I'm not using NSAttributedStrings here, only changing the stringValue of the NSTextFields, and of course their textColor.
Everything is working... except that sometimes, the text fields have an unexpected slightly dark semi-transparent background.
(It's hard to see on some screens but it's there.)
Question: why does this darker background appear?
And of course: what could I do to fix it?
I'm pretty sure it's the gradient that breaks something but I can't find what...
Note: the project is in Swift but I can read an Objective-C answer.
EDIT:
So indeed it seems to be coming from the gradient that's behind, see this other screenshot from a test window. This time the gradient is drawn in a Custom View under an NSTextView, and the same undesired effect happens: parts of the text field background are visible but shouldn't.
UPDATE:
I have made a very simple example in a project for testing, with a gradient that shows the phenomenon more visibly. There's only a window, my gradient class and a text field. You can get it (30ko only) in this ZIP file.
You always draw the gradient in the dirty rect. When the text changes, that rect is only the size of the textfield, not of the whole view. Your drawRect function then draws the full gradient in the textfield's background rect, rather than just the portion of the background-view-wide gradient you'd see through the textfield.
If you redraw using your view's frame, and ignore the dirty rect argument, you should get the desired appearance.
I'm guessing your text field isn't layer-backed. If not, turn on layers (in IB or via -wantsLayer for the view in code) for at least the text field. If that alone doesn't work, try turning on layers for the gradient-hosting view as well.

NSClipView ghosting, artifacts, trails on setDrawsBackground:NO

I'm trying to get NSClipView to either draw a clear background (set the color to clear results in a black box), or no background at all. Drawing no background results in ghosting artifacts. Anyway to get this to draw no background without the artifacts???
The NSClipView is contained inside an NSBox subclass. An NSTextView is contained inside the NSClipView. It's basically an attempt at rolling my own NSTextField. I need to be able to draw a custom background and included subviews such as buttons.
The trails behavior is noted in the documentation of NSClipView. If the clip view is contained in a NSScrollView the documentation suggests calling setDrawsBackground: on the scroll view instead.
You could also try setting the background color of the scroll view to the clear color, assuming that the clip view is in a scroll view.
If the clip view is not in a scroll view then you might want to explain what the view hierarchy is like, and any code relavent to its construction.

How can I change the way NSButtonCell objects highlight when clicked?

I am using several NSButtonCell objects in an NSTableView. They are simple square buttons with custom images on them.
These buttons draw properly when they are not highlighted: all that is visible is the image, and the rest of the button rectangle is transparent. However, when I click on them, the entire button rectangle is highlighted, inverting the background in the parts that were transparent.
I would prefer to see the image drawn inverted, and the transparent parts remain transparent. How can this be done?
Try setting your cell's highlightsBy property to NSContentsCellMask. I think you'll have to do this in code (probably in awakeFromNib); I don't see a way to do it in IB alone.
You can do it in Interface Builder too. I use "Square Button" so the button alters between two images (so the image is not inverted at all).
Your buttons behaviour is probably set to "Momentary Light" or "Momentary Push In".
Set the Behaviour to "Momentary Change", and it should work.

Resources