UIView. Why Does A Subviews Outside its Parent's Extent Not Receive Touches?

dugla picture dugla · Apr 30, 2011 · Viewed 9.9k times · Source

I have a simple - trivial - UIView parent/child hierarchy. One parent (UIView). One child (UIButton). The parents bounds are smaller then it's child's bounds so that a portion of the child extends beyond the bounding box of its parent.

Here's the problem: Those portions of the child outside the bbox of the parent do not receive touches. Only tapping within the bbox of the parent allows the child button to receive touches.

Can someone please suggest a fix/workaround?

UPDATE

For those following this question, here is the solution I implemented as a result of @Bastians most excellent answer:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

    BOOL isInside = [super pointInside:point withEvent:event];

    // identify the button view subclass
    UIButton *b = (UIButton *)[self viewWithTag:3232];
    CGPoint inButtonSpace = [self convertPoint:point toView:b];

    BOOL isInsideButton = [b pointInside:inButtonSpace withEvent:nil];

    if (isInsideButton) {

        return isInsideButton;

    } // if (YES == isInsideButton)

    return isInside;        
}

Answer

Bastian picture Bastian · Apr 30, 2011

The problem is the responder chain. When you touch the display it will go down from the parents to the childen.

So .. when you touch the screen the parent will see that the touch is outside of it's own bounds and so the children will not even asked.

The function that does that is the hitTest. If you have your own UIView class you can overwrite it and return the button by yourself.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event