fill the void - bdunagan

01 Mar 2010
iPhone Tip: Larger Hit Area for UIButton

2010-08-18 Update: I added a section explaining how to programmatically grow the touchable area of a UIButton via hitTest.

Apple’s iPhone HIG estimates 44x44 pixels is a good hit area for a UI element. If the button isn’t that big, don’t let the user realize that: make the hit area larger than the button.

The UINavigationItem button is an excellent example of this larger hit area. Try touching near (but not on) the standard “Back” button in any navigation-based iPhone app. It responds. I never even noticed this interaction until I started this post, and that’s precisely the goal.

But when Apple doesn’t auto-extend the hit area, the developer should. There are two approaches:

A Larger Target

I can programmatically grow the area of the button by subclassing UIButton and overriding UIView::hitTest:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
	int errorMargin = 30;
	CGRect largerFrame = CGRectMake(0 - errorMargin, 0 - errorMargin, self.frame.size.width + errorMargin, self.frame.size.height + errorMargin);
	return (CGRectContainsPoint(largerFrame, point) == 1) ? self : nil;

An Invisible Button

For the invisible button, use Interface Builder to create a large UIButtonTypeCustom UIButton, hook up its touchDown, touchUpInside, touchUpOutside events to custom selectors in the controller, and use UIButton::setHighlighted on the original button to mimic a real tap, as described in this spot-on StackOverflow comment. (And don’t try setting the button’s alpha to zero; the button will no longer respond to touch events.)

Either way, an oversized hit area is especially necessary for smaller buttons, like the 29x31 “Detail Disclosure” button (UIButtonTypeDetailDisclosure) or the 18x19 “Info Light” button (UIButtonTypeInfoLight). Try simply adding the “Info Light” i button to a blank screen, running it on a device, and tapping it; it’s frustratingly small.

Previous LinkedIn Twitter GitHub Email Next