UIViews
iOS Development
Touch Events
User Interface
Objective-C

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:

swift
1import UIKit
2
3final class PassthroughView: UIView {
4    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
5        return false
6    }
7}

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.

swift
1import UIKit
2
3final class OverlayView: UIView {
4    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
5        let hitView = super.hitTest(point, with: event)
6        return hitView === self ? nil : hitView
7    }
8}

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:

objective-c
1- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
2    UIView *hitView = [super hitTest:point withEvent:event];
3    if (hitView == self) {
4        return nil;
5    }
6    return hitView;
7}

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 nil or false from 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.

Course illustration
Course illustration

All Rights Reserved.