 <p>I've come up with an alternate solution that to me seems safer than LombaX's. It uses the fact that both events come in with the same timestamp to reject the subsequent event.</p> <pre><code>@interface RFNavigationBar () @property (nonatomic, assign) NSTimeInterval lastOutOfBoundsEventTimestamp; @end @implementation RFNavigationBar - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // [rfillion 2014-03-28] // UIApplication/UIWindow/UINavigationBar conspire against us. There's a band under the UINavigationBar for which the bar will return // subviews instead of nil (to make those tap targets larger, one would assume). We don't want that. To do this, it seems to end up // calling -hitTest twice. Once with a value out of bounds which is easy to check for. But then it calls it again with an altered point // value that is actually within bounds. The UIEvent it passes to both seem to be the same. However, we can't just compare UIEvent pointers // because it looks like these get reused and you end up rejecting valid touches if you just keep around the last bad touch UIEvent. So // instead we keep around the timestamp of the last bad event, and try to avoid processing any events whose timestamp isn't larger. if (point.y &gt; self.bounds.size.height) { self.lastOutOfBoundsEventTimestamp = event.timestamp; return nil; } if (event.timestamp &lt;= self.lastOutOfBoundsEventTimestamp + 0.001) { return nil; } return [super hitTest:point withEvent:event]; } @end </code></pre>