Currently I have a little issue when it comes to buttons(NSButton
) which have a tracking area and views(NSView
overlay) above these buttons, this is my setup:
Custom button:
class AppButton: NSButton {
override func updateTrackingAreas() {
super.updateTrackingAreas()
let area = NSTrackingArea(
rect: self.bounds,
options: [.mouseEnteredAndExited, .activeAlways],
owner: self,
userInfo: nil
)
self.addTrackingArea(area)
}
override func mouseEntered(with event: NSEvent) {
NSCursor.pointingHand.set()
}
override func mouseExited(with event: NSEvent) {
NSCursor.arrow.set()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
An instance of this button class is used i a very basic NSView
.
When I hover over the button, the cursor changes correctly.
When I click the button a new overlay(NSView
) is opened above the button...
This is where the problem starts:
When I hover over the overlay where my button is placed, the cursor still changes...
I did not know that a NSTrackingArea
is going through all views..
How can i solve this issue?
Can I set any property on the overlay(NSView
) to somehow disable the NSTrackingArea
on the button?
Thanks!!
You can subclass NSView
and add local monitoring for events. Check if the event has occurred over the view and if true return nil. This will avoid propagating the events being monitored. If the event is outside the view frame you can propagate it normally returning the event monitored.
class CustomView: NSView {
override func viewWillMove(toSuperview newSuperview: NSView?) {
super.viewWillMove(toSuperview: newSuperview)
wantsLayer = true
layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor
layer?.borderWidth = 1
NSEvent.addLocalMonitorForEvents(matching: [.mouseEntered, .mouseExited, .leftMouseDown]) { event in
if self.frame.contains(event.locationInWindow) {
// if cursor is over the view just return nil to do not propagate the events
return nil
}
return event
}
}
}