Skip to content

Instantly share code, notes, and snippets.

@iby
Last active December 18, 2022 11:02
Show Gist options
  • Save iby/d105f040a65f74aeccfeb6cb707bf9e0 to your computer and use it in GitHub Desktop.
Save iby/d105f040a65f74aeccfeb6cb707bf9e0 to your computer and use it in GitHub Desktop.
Overlap test for NSView with tracking areas
import AppKit
extension NSView
{
/// Checks if view overlaps with other views above it at specified **window** location.
func overlapTest(_ point: NSPoint) -> Bool {
// Perform hit test to get the view under mouse. Because it can be a view within
// our tested view we should also check superviews. There might also be views that
// overlap, but are not interactive, in which case for this to work as expected
// they must correctly implement hit test.
var view: NSView? = self.window?.contentView?.hitTest(point)
while view != nil && view !== self { view = view?.superview }
return view !== self
}
}
/// This can be used as a base for non-interactive views, which also works with interface builder.
@IBDesignable class View: NSView
{
@IBInspectable var ignoresMouseEvents: Bool = false
override func hitTest(_ point: NSPoint) -> NSView? {
return self.ignoresMouseEvents ? nil : super.hitTest(point)
}
}
/// Custom view with tracking area…
@IBDesignable class MyView: NSView
{
// …
override func mouseEntered(with event: NSEvent) {
guard !self.overlapTest(event.locationInWindow) else { return }
// Good to go!
}
// …
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment