Passing through touches to UIViews underneath
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In UIKit, the topmost view under a touch normally receives the event, which means an overlay blocks touches from reaching views underneath it. If you want touches to pass through, the usual solution is to customize hit-testing so the overlay returns nil for areas that should not intercept touches. The important part is to do this intentionally, because touch pass-through changes user interaction rules and can easily become confusing if overused.
How UIKit Decides Who Gets the Touch
When the user touches the screen, UIKit performs hit-testing from the top of the visible view hierarchy downward. The view that wins hit-testing receives the touch events.
That means an overlay view on top naturally blocks underlying controls unless you override the default behavior.
Simple Pass-Through Using point(inside:with:)
If the overlay should never receive touches at all, the simplest approach is to report that no point is inside it.
Swift example:
With this override, the overlay is visually present but does not become the hit-tested target. Touches fall through to whatever view is underneath.
Use hitTest(_:with:) for More Control
If only some parts of the overlay should pass touches through, override hitTest(_:with:) instead.
This pattern lets the overlay’s interactive subviews still receive touches while empty areas of the overlay itself pass touches to underlying views.
That is often the more practical solution.
Objective-C Version
Since this topic often appears in older UIKit codebases, here is the same idea in Objective-C:
This means:
- if a subview on the overlay is hit, keep that result
- if only the overlay itself was hit, ignore it and let the touch continue downward
When This Is Useful
Touch pass-through is useful for UI patterns such as:
- decorative overlays
- transparent tutorial masks with specific interactive holes
- heads-up displays that should not block the whole screen
- partially interactive container views
The common theme is that the overlay exists visually, but should not own every touch in its frame.
When It Is the Wrong Tool
If the overlay actually represents modal state, disabling interaction underneath is often the correct behavior. Passing touches through a modal overlay can create confusing UX because the interface looks blocked but still responds underneath.
So before implementing pass-through, ask whether the design should instead:
- disable the underlying controls explicitly
- move the overlay elsewhere in the hierarchy
- use a non-blocking visual effect rather than a full overlay view
Test With Real Interaction, Not Just Taps
Touch behavior affects more than basic taps. It can also affect:
- scrolling
- gesture recognizers
- buttons near overlay boundaries
- accessibility interactions
A pass-through view that seems correct in a simple tap test can still behave unexpectedly once gestures and overlapping interactive regions are involved.
Common Pitfalls
A common mistake is overriding hit-testing too broadly and making the overlay impossible to interact with, even when some overlay subviews should still handle touches.
Another issue is forgetting that gesture recognizers and scroll views are part of the touch system too. Pass-through can change more than button taps.
Developers also sometimes use pass-through to work around poor view hierarchy design when restructuring the UI would be clearer and safer.
Finally, if an overlay looks modal but passes touches underneath, users may perceive the app as buggy rather than clever.
Summary
- UIKit normally sends touches to the topmost hit-tested view.
- To pass touches through, return
nilorfalsefrom the right hit-testing override. - Use
point(inside:with:)when the overlay should never intercept touches. - Use
hitTest(_:with:)when only certain overlay areas should pass touches through. - Test gesture and UX behavior carefully before keeping touch pass-through in production.

