Search code examples
macoscocoansviewhittestnsclickgesturerecognizer

NSClickGestureRecognizer.location(in:) and hitTest()


I have the following view:

Screenshot

which has a custom class based on NSVisualEffectView, and contains an image view, a label (NSTextField) and a popup button. isFlipped of the custom view is always false.

The custom view also contains a NSClickGestureRecognizer which uses a delegate. The delegate implements just one method:

func gestureRecognizerShouldBegin(_ gestureRecognizer: NSGestureRecognizer) -> Bool {
    let thePoint = gestureRecognizer.location(in: view)

    if let theView = view.hitTest(thePoint) {
        return !theView.handlesMouseEvents
    }
    else {
        return true
    }
}

If I click in the middle of the popup menu, location(in:) returns the value (182, 16) for instance. This seems correct for me for a non-flipped view. But hitTest() returns the background view for that point as result and not the popup button.

What am I doing wrong?

If I use the manually flipped point (y := height - y) for hit-testing I get the popup button as result. But I don't want to use that approach because it seems ugly to me.

If seems to work if I use the window's content view for hit-testing. But I would still like to know why the approach shown does not work.


Solution

  • The parameter point of hitTest(_:) is

    A point that is in the coordinate system of the view’s superview, not of the view itself.

    Solution: pass a point in superview coordinates.