Abolfoooud
Abolfoooud

Reputation: 2703

Define custom touch area in custom UIControl object

I am creating a custom UIControl object as detailed here. It is all working well except for the touch area.

I want to find a way to limit the touch area to only part of the control, in the example above I want it to be restricted to the black circumference only rather than the whole control area.

Any idea? Cheers

Upvotes: 3

Views: 715

Answers (1)

Nikolai Ruhe
Nikolai Ruhe

Reputation: 81868

You can override UIView's pointInside:withEvent: to reject unwanted touches.

Here's a method that checks if the touch occurred in a ring around the center of the view:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    UITouch *touch = [[event touchesForView:self] anyObject];
    if (touch == nil)
        return NO;

    CGPoint touchPoint = [touch locationInView:self];
    CGRect bounds = self.bounds;

    CGPoint center = { CGRectGetMidX(bounds), CGRectGetMidY(bounds) };
    CGVector delta = { touchPoint.x - center.x, touchPoint.y - center.y };
    CGFloat squareDistance = delta.dx * delta.dx + delta.dy * delta.dy;

    CGFloat outerRadius = bounds.size.width * 0.5;

    if (squareDistance > outerRadius * outerRadius)
        return NO;

    CGFloat innerRadius = outerRadius * 0.5;

    if (squareDistance < innerRadius * innerRadius)
        return NO;

    return YES;
}

To detect other hits on more complex shapes you can use a CGPath to describe the shape and test using CGPathContainsPoint. Another way is to use an image of the control and test the pixel's alpha value.

All that depends on how you build your control.

Upvotes: 6

Related Questions