You have explained very beautifully the cause of the problem. On iOS 5, a UITapGestureRecognizer on a button's superview interferes with the action of the button. On iOS 6, they fixed this: they introduced a UIView event gestureRecognizerShouldBegin:
, and a button automatically returns NO for a tap gesture recognizer attached to a superview.
For iOS 5, you'll need to use a delegate method on the tap gesture recognizer to stop it from recognizing if the tapped view was the button.