How to pass the touch event to superview when userInteractionEnabled = YES?

15,118

Solution 1

You could try overriding the pointInside:withEvent: method in your inner view. This will allow you to return NO when you want to forward touches to the superview:

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    if( /* You have content, and you want to receive touches */){
        return YES;
    }else{
        return NO;
    }
}

Solution 2

You can subclass your subview, and implement

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!touchedContent) {
        [[self nextResponder] touchesBegan:touches withEvent:event];
    } else {
        [super touchesBegan:touches withEvent:event];
    }
}

Solution 3

You can use another UIView to "hide" the subview.

*Details : This UIView is the subview's sibling . it has the same size and position of your subview with background color of clear color.

*Explain: The new UIView will take the touch, and automatically pass it to the superview.

This way doesn't need to subclass your subview - it's a storyboard solution.
Please try this. Have fun!

Share:
15,118
Earl Grey
Author by

Earl Grey

In elusive pursuit of perfection. I find myself at the intersection of design and programming daily, trying to figure out the best way programming should serve design.

Updated on June 05, 2022

Comments

  • Earl Grey
    Earl Grey almost 2 years

    I have the following setup.

    +- XXXCustomControl : UIControl -------+
    | A                                    |
    |   +- ContentView -------------------+|
    |   |                                 ||
    |   |  B                              ||
    |   |                                 ||
    |   +---------------------------------+|
    +--------------------------------------+ 
    

    A XXXCustomControl that is a subclass of UIControl. It contains one subview called contentView of type UIView with size that is smaller than the Control's area.. That view has .userInteractionEnabled = YES;

    I need that property to have set to YES, because horizontal scrollviews are put inside this once in a while and they need to be scrollable. If the superview (in our case content view would not allow user interaction, this is inherited y the subviews.) But at the same time this XXXCustomControl need to be tappable when it contains no scrollview in its content view not only in area A but also in area B.

    So I have a "conflict of interests" here because I either

    1) set the content view to userInteractionEnabled = NO, then I can tap the empty control in the content view area both in A and B, but the scrollviews I will put there won't be scrollable..

    2) set the content view to userInteractionEnabled = YES but then, if the Control s empty, I can only tap area A to trigger a touch event.

    One idea I came up with is that I set the property to NO by default and when I populate the contentView I set it to yes. when I clear the contentView I set the property back to no. Basically I want this to have set to yes all the time, and when it is empty ,force the contentView to pass the touchUpInside event up to its superview.

    Is this possible?