Overlapping Circular Buttons and Hit/Tap Testing

2019-05-26 19:52发布

问题:

I am trying to create a Tabla drum app (a Table is a pair of small hand drums attached together). To do this I want to use a button for each section of the drum by putting one on top of another. Like so:

I've tried using a circular image for the button but the surrounding area are a rectangle. That means when the user would hit parts of the green circle it plays the sound for the orange circle (I hope that makes sense).

How can I ensure the sound for the green pad is played when the user taps in the green pad, and the sound for the orange pad is played when the user taps the orange pad?

回答1:

There is no "simple way" to limit the tap-detection area. You are perfectly correct: the button's tap-detection area is its rectangle, and that's all it knows about. Therefore, you can't use the button's simple tap-detection to do the work for you. You are going to have to detect the tap yourself, look at where it is, and use that knowledge plus your knowledge of where the drawings of the circles are to decide which section of the drum the user tapped in.

Look at UITapGestureRecognizer for a way to find out that the user tapped and where.

Look at UIBezierPath for a way to do hit detection with respect to a shape (e.g. a circle, answering the question, "is this point in this circle").

Your best bet might be to modify the built-in hit-testing, i.e. a UIButton or UIView subclass in which you override pointInside:withEvent: to return YES only if the point is within the interior circle, e.g.:

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:self.bounds];
    return [p containsPoint:point];
}

That is about as "simple" as it's going to get, I'm afraid.