UITapGestureRecognizer tap on self.view but ignore subviews
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When a UITapGestureRecognizer is attached to self.view, taps on subviews can still participate in that recognizer unless you filter them out. If you want the recognizer to fire only when the user taps the root view itself, the usual solution is to use the gesture recognizer delegate and reject touches whose touch.view is a subview.
Why the Default Behavior Includes Subviews
Gesture recognizers work with UIKit hit-testing. If a tap lands on a button, label, or custom child view inside self.view, that touch still belongs to the overall view hierarchy rooted at self.view.
So adding a recognizer to self.view does not automatically mean:
- trigger only on the exact background view
It often means:
- observe taps anywhere in the part of the hierarchy where the recognizer is attached
That is why delegate filtering is the standard fix.
Use UIGestureRecognizerDelegate
Implement gestureRecognizer(_:shouldReceive:) and accept only touches whose view is exactly self.view:
The identity check === matters. It verifies that the touched view is the same instance as self.view, not a descendant.
Why cancelsTouchesInView Often Helps
If subviews such as buttons or table cells should continue to receive their normal touches, set:
Without that, the gesture recognizer may interfere with subview interaction depending on how recognition resolves.
Ignoring Only Certain Subviews
Sometimes you do not want a strict root-view-only rule. You may only want to ignore taps on interactive controls:
This is useful for background-tap gestures that dismiss the keyboard while still allowing buttons to work normally.
Ignoring a Specific Subtree
If you want to ignore taps inside one specific container, use isDescendant(of:):
This gives you more control than a simple equality check.
Typical Use Cases
This pattern is common when:
- dismissing the keyboard on background taps
- closing an overlay when the user taps outside content
- handling background-only taps without breaking subview controls
The key is to define clearly what should count as "background" in your hierarchy.
Common Pitfalls
The biggest mistake is assuming a recognizer attached to self.view automatically ignores subviews. It does not.
Another mistake is forgetting to set the recognizer's delegate. Without that, shouldReceive never runs.
People also compare against the wrong view. touch.view is the deepest hit-tested view, so equality with self.view is a strict filter.
Finally, if subviews stop responding after adding the tap recognizer, check cancelsTouchesInView and your gesture-recognition interactions.
If multiple recognizers are active on the screen, also review simultaneous-recognition rules so your background tap recognizer does not accidentally compete with higher-priority gestures.
Summary
- A tap recognizer on
self.viewcan still observe taps on subviews. - Use
UIGestureRecognizerDelegateandgestureRecognizer(_:shouldReceive:)to filter touches. - Return
touch.view === self.viewwhen only direct taps on the root view should count. - Set
cancelsTouchesInView = falsewhen subviews should keep their normal touch behavior. - Use type checks or descendant checks when you need more selective filtering.
Related reading
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.