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.