I have a NSTextView, non-editable, non-selectable, in a NSView. I need the NSView to receive click events when the text view is clicked - basically I need the click events to act as though the text view doesn't even exist. Obviously I would just use the
textView:clickedOnCell:inRect:atIndex:
text view delegate method, but I need to capture the click event, to detect double-clicks and things like that.
In the view that contains the text view, override the hitTest:
method to return self
. The mouse events will then be sent to the container view.
I've since found that hitTest:
will be called for click and mouse-tracking events anywhere in the window, even for events that wouldn't naturally be anywhere near the container view. If there are other views in the window, your hitTest:
method will turn the container view into a black hole that causes all of those events to gravitate into itself, never to be seen by any other views.
The fix for that is to test whether the event is within your view before swallowing it. If it is, return self
; if it isn't, return nil
.
The simplest way to do that is to call super
's implementation, which will return the view or any subview of itself if the point is within the view, and then just return self
if that method returned non-nil
. If it returned nil
, then you return nil
, too.
A less-simple but possibly more efficient method would be to convert the point from the window's coordinate system to the view's, then use NSPointInRect
to test whether the point is within the view's bounds
.
Just to put Peter's fantastic description into code:
- (NSView *)hitTest:(NSPoint)aPoint
{
NSView *result = [super hitTest:aPoint];
if (result)
{
result = self;
}
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With