Alexander Bollbach
Alexander Bollbach

Reputation: 659

Hit Testing a UIButton located outside bounds of SuperView

I am trying to animate this view ControlsView up by touchUpInside in the UIButton which is the caret character inside the white square in the image attached. When the button is hit, a delegate method is fired an the controlsView is animated up. The problem is that because the UIButton is outside of the bounds of controlsView it does not receive touch info.

I have thought about this a lot and read up on some potential candidate solutions. Such as detecting the touch event on a super view by overriding hitTest:withEvent:. However, the UIButton is actually a subview of CockPitView which is a subview of ControlsView which is a subview of MainView. MainView, it seems, is the rectangle whose coordinates the UIButton would truly lie in. So would I override hitTest there and pass the touch info to CockPitView, where I could then have my Button trigger its action callback?

Has anyone encountered this or a similar problem and have any advice on how to proceed?

visual reference

Upvotes: 0

Views: 2343

Answers (2)

liuyaodong
liuyaodong

Reputation: 2567

You may want to use -pointInside:withEvent:. In your button's superview, i.e., ControlsView, override the method like this:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    // self.button is the button outside the bounds of your ControlsView
    if (CGRectContainsPoint(self.button.bounds, [self convertPoint:point toView:self.button])) {
        return YES;
    }
    return [super pointInside:point withEvent:event];
}

By doing this, your ControlsView claims that the points inside the bounds of your button should be treated like the points inside your ControlsView.

Upvotes: 1

tuledev
tuledev

Reputation: 10317

You should override hitTest in your custom view CockPitView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{   
    if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
        for (UIView *subview in self.subviews.reverseObjectEnumerator) {
            CGPoint subPoint = [subview convertPoint:point fromView:self];
            UIView *result = [subview hitTest:subPoint withEvent:event];
            if (result != nil) {
                return result;
            }
        }
    }

    return nil;
}

CockPitView has to be a subclass of UIView

Upvotes: 3

Related Questions