NSButton background transparent after getting focus
The following is tested for NSTextField, but should work for buttons as well.
Set the appearance
property of the NSButton
to NSAppearanceNameAqua
. Because if the button doesn't try to do some weird vibrancy effect, he can't mess things up. The labels still look the same and the strange effect is gone.
My words in code:
self.button.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
Custom NSButton with semi-transparent background
The default operation of NSRectFill()
is copy which is not what you want. Replace it with
NSRectFillUsingOperation(dirtyRect, NSCompositeSourceAtop);
NSButton turns gray when pushed
A lot of this was already said by both Willeke and I'L'I, so credit goes to them.
What Willeke said:
Never do anything in draw()
except drawing. This method can get called as often as the screen refreshes. So currently you are basically trying to add yourself as the observer of the notificationCenter really often.
Here is what you could do:
Write a setup()
method and call that from each initialiser. Any one of them is called once for a button instance.
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupButton()
}
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.setupButton()
}
private func setupButton() {
self.image = NSImage(named: "buttonImage.png")
NotificationCenter.default.addObserver(forName: .windowChanged, object: nil, queue: nil) {
notification in
self.image = NSImage(named: "buttonImage_highlighted.png")
}
}
You do not need to add the init(frame:)
initialiser here. For storyboards the init(coder:)
one is sufficient. I added it anyways, because you might want to initialise the button programmatically. You use the init(frame:)
method there usually. If you add convenience methods, make sure to call the setup()
method there as well.
What I'L'I said:
To the important stuff:
What I did to suppress the grey background on mouseDown was to simply call isHighlighted = false
before calling super.draw(rect)
.
override func draw(_ dirtyRect: NSRect) {
self.isHighlighted = false
super.draw(dirtyRect)
}
Bonus:
I see you somewhere defined a Notification.Name
. You can define all of them in a project global extension to Notification.Name
like this:
extension Notification.Name {
static let windowChanged = Notification.Name(rawValue: "WindowChangedNotification")
}
After that you can use them everywhere like system notification names.
NSButton's images lose transparency on selection
The issue was that I was customising a 'Bevel' button. I changed the button bezel to 'Square' and changed the button type to 'Momentary Change'.
Hope this helps some people in the future!
NSButton white background when clicked
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];
Bleed through from NSButton checkbox on non-transparent NSPopover
The answer, thanks to Willeke, is to add this within AppDelegate.applicationDidFinishLaunching()
popover.appearance = NSAppearance(named: .aqua)
Disable Transparency on NSPopover for Certain Controls
I figured this out - overriding the allowsVibrancy
property of the button to return NO
disables the transparency effect.
Objective-C:
- (BOOL)allowsVibrancy {
return NO;
}
Swift:
override var allowsVibrancy: Bool { return false }
Related Topics
Sktexture Nearest Filtering Mode Doesn't Work (Making Pixel Art)
Swift: Generics and Type Constraints, Strange Behavior
Implementing Swift Protocol Methods in a Base Class
Dictionary of String:Any Does Not Conform to Protocol 'Decodable'
Type Check Operator (Is) for Check VS Homogenous Protocol: Why Can This Be Done for Optionals
Swiftui View and Uihostingcontroller in Uiscrollview Breaks Scrolling
Why Is Deinit Not Called Until Uiview Is Added to Parent Again
Swift: Convert String to Hex Color Code
How to Get Walking and Running Distance Using Healthkit in Swift
Playing Hls (M3U8) in Cocoa Os X Avplayer - Swift
Swift 2 Error Handling and While
Swiftui Button Interact with Map
Swift 3 Type Inference Confusion
How to Apply Animation for One Specific Modifier Change Only