I create a subclass of NSView that draw a red filled circle and i'd like to intercept mouse click that came into Red Circle only and not in transparent pixels.
I think that i have to work with hitTest:
function, but i'm not sure this's the right way.
(My view has AcceptFirstMouse
and MouseDown
implementation, isOpaque
return NO.)
What can i 开发者_如何学Pythondo to obtain this behavior ?
Using hitTest:withEvent:
won't help you in this case, since the point will pass this test if it is anywhere inside the view's frame.
Maybe (quite) simple calculations will do what you want, assuming you at least know the circle's center position (maybe just the same as the view one), and the radius of your circle. The problem is now determining if the distance between the circle's center and your point is less than the radius.
Then you can easily write a function, for instance :
+(BOOL)ispoint:(CGPoint)aPoint inCircleWithCenter:(CGPoint)aCenterPoint
radius:(CGFloat)aRadius {
CGFloat squareDistance = (aCenter.x - aPoint.x) * (aCenter.x - aPoint.x) +
(aCenter.y - aPoint.y) * (aCenter.y - aPoint.y);
return squareDistance <= aRadius * aRadius;
}
We can actually discuss the <=
, which could just <
... This is a class method you can equip your custom subclass with. Or write a function :
BOOL CGPointInCircle(CGPoint aPoint, CGPoint aCenter, CGFloat aRadius) {
CGFloat squareDistance = (aCenter.x - aPoint.x) * (aCenter.x - aPoint.x) +
(aCenter.y - aPoint.y) * (aCenter.y - aPoint.y);
return squareDistance <= aRadius * aRadius;
}
It sounds like hitTest:
is what you want. Assuming you're using an NSBezierPath to draw the circle, just implement hitTest:
as [path containsPoint:[self convertPoint:testPoint fromView:[self superview]]] ? self : nil
.
精彩评论