iOS Development
hitTest:withEvent:
UIView
Event Handling
Objective-C

Capturing touches on a subview outside the frame of its superview using hitTestwithEvent

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A subview can draw outside its superview’s bounds, but UIKit does not normally deliver touches outside the superview’s bounds to that child. The reason is simple: the superview fails the hit test first, so the search never reaches the overflowing subview. To fix that, override hit-testing on the parent and explicitly forward touches into the child’s coordinate space when the point lands inside the visible overflow area.

Why the Default Behavior Fails

Touch delivery starts at the window and walks down the view tree. Each view is asked whether the touch point is inside it and which descendant should receive the event.

If a child visually extends beyond its parent’s frame, the parent still only considers its own bounds by default. So the portion of the child that lies outside the parent becomes untouchable.

This is a hit-testing rule, not a drawing rule.

Override the Parent’s hitTest:withEvent:

The usual fix is to override the superview’s hitTest:withEvent: and manually test the child using converted coordinates.

objective-c
1- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
2    if (self.hidden || self.alpha <= 0.01 || !self.userInteractionEnabled) {
3        return nil;
4    }
5
6    UIView *child = self.expandedSubview;
7    CGPoint childPoint = [child convertPoint:point fromView:self];
8
9    if ([child pointInside:childPoint withEvent:event]) {
10        return [child hitTest:childPoint withEvent:event];
11    }
12
13    return [super hitTest:point withEvent:event];
14}

Here, expandedSubview is the child that visually extends beyond the parent.

What the Coordinate Conversion Does

The touch point arrives in the parent’s coordinate system. The child needs the point expressed in its own coordinates.

objective-c
CGPoint childPoint = [child convertPoint:point fromView:self];

Without this conversion, the hit test uses the wrong coordinate space and behaves inconsistently.

It also makes debugging easier. Once the point is converted, you can log or inspect it relative to the child’s bounds instead of trying to reason across two coordinate systems at once.

Keep the Overflow Intent Narrow

You usually do not want to forward every touch outside the parent’s bounds to every child. Restrict the custom logic to the specific subview or small set of subviews that are supposed to be interactive outside the parent frame.

That keeps hit-testing predictable and avoids surprising event routing later.

Alternative: Override pointInside:withEvent:

In some layouts, overriding pointInside:withEvent: on the parent can also work by making the parent report YES for touches in the overflow area. But if you need to route the touch carefully to a specific child, overriding hitTest:withEvent: gives you more control.

For that reason, hitTest:withEvent: is usually the better tool for this specific problem.

Clipping and Hit Testing Are Separate Concerns

Setting clipsToBounds changes whether the overflowing child is visibly clipped, but it does not solve the touch-routing problem by itself. Developers often fix the visual overflow and then assume interaction will follow automatically. UIKit treats those as separate decisions.

Common Pitfalls

  • Assuming visible overflow automatically becomes touchable overflow.
  • Forgetting to convert the touch point into the child’s coordinate system.
  • Returning the parent view directly when the child should receive the touch.
  • Applying the custom hit-test logic to every subview instead of the intended target.
  • Debugging layout constraints when the real issue is hit-testing order.

Summary

  • A child outside its parent’s bounds does not receive touches there by default.
  • The parent must participate in hit-testing for the overflow area.
  • Override hitTest:withEvent: on the parent and convert the point into the child’s coordinates.
  • Forward only the touches that belong to the intended overflowing subview.
  • Treat this as an event-routing problem, not a drawing problem.

Course illustration
Course illustration

All Rights Reserved.