Search code examples
iosuigesturerecognizeruitouchtouchesbegan

iOS define touchable areas of an object, confine touches to subviews of self


I have a subclassed UIView I'll call customView. I would like enable touches so users can manipulate subviews, which have gesture recognizers and other controls, but the view itself I would like to not be touchable so that views drawn below the view will still be touchable. In other words customView will be drawn on top of other views in the app, but I still want the views below to be touchable, while allowing touches on subviews of customView.

I've tried to use touchesBegan like so but this does not work. Any ideas? Thanks for reading!

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];

//I've tagged the views that I want to be touchable.
    if ([touch view].tag == 1000 || [touch view].tag == 2000 || [touch view].tag == 3000) {
        self.userInteractionEnabled = YES;
    } else {
        self.userInteractionEnabled = NO;
    }
}

Solution

  • What you need to do is implement the following method in your customView:

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    {
        //check if one of the subviews was hit, if so forward the touch event to it
        for (UIView *view in self.subviews){
            if (CGRectContainsPoint(view.frame, point))
                return view;
        }
    
        // use this to pass the 'touch' upward in case no subviews trigger the touch
        return [super hitTest:point withEvent:event];
    }