3

I have a custom button (which uses a a circled shaped image as its custom view). The problem is: the active area of the custom button is much too large, if I tap at least 100 pixels outside the button, it still gets registered as a tap on the button. This results in accidental taps.

Note:- I don't want to reduce size of button as it is already bigger that minimum requirement. I want to reduce tappable space.

How can I reduce the active area on these buttons?

user1288005
  • 890
  • 2
  • 16
  • 36

1 Answers1

2

If your button isn't already a subclass of UIButton, it will have to be to achieve this. You can override pointInside:withEvent: to alter the "touchable" area to any arbitrary shape you want. A subclass that simply alters the hit box's insets might look something like this:

// --HEADER--
@interface TouchInsetButton : UIButton
@property (nonatomic, assign) UIEdgeInsets touchInsets;
@end

// --IMPLEMENTATION--
@implementation TouchInsetButton
@synthesize touchInsets = _touchInsets;

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGRect modifiedHitBox = UIEdgeInsetsInsetRect([self bounds], _touchInsets);
    return CGRectContainsPoint(modifiedHitBox, point);
}

@end

Just note that, as you noticed, UIButtons normally use a bounding box that's slightly larger than their bounds. Just using this subclass without setting any insets will result in a button that only accepts hits that are completely within the button's bounds.

Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
  • Overriding `pointInside` is correct. Since the OP's button is circular, it will need some Pythagoras, not just `CGRectContainsPoint`. For really complex shapes, construct a `UIBezerPath` in the shape of the button outline, and call `containsPoint` on that. – Cowirrie Jul 19 '12 at 06:33
  • This does not work for me. If I enlarge the touchable area around the button by using negative inset values, the button does not recognize taps near the outer edges of the inset area. The pointInside:withEvent method is returning YES, and I can see the button image blink when tapped, but the button's target selector is never called. However, if I change the control event to UIControlEventTouchDown then everything works as expected. – dmarnel Jan 29 '13 at 22:50