Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent parent view from receiving touch event after child view acts on it

I'm having a trouble with the responder chain of events on an iOS app.

The problem is the following, I have a set of subviews (bubbles) on a bigger view (square) and I want to be able to show a certain view if I tap on the buttons, however if I tap anywhere else I want the same view to hide.

The problem is when I tap a bubble, both views (child and parent) are triggering, how can I prevent this?

If the child already acted on a touch event shouldn't that be the end of it?

My Bubbles are recognizing the Tap gesture with UITapGestureRecognizer while the parent view (square) uses touchesBegan: method

This graph explains my current setup with multiple bubbles:

enter image description here

Code:

@implementation Bubble
...
-(id) initWithFrame: (CGRect) frame {
    UITapGestureRecognizer *singleFingerDTap = [[UITapGestureRecognizer alloc]
                                                initWithTarget:self action:@selector(handleSingleTap:)];
    singleFingerDTap.numberOfTapsRequired = 1;
    [self addGestureRecognizer:singleFingerDTap];

}

-(void) handleSingleTap {
NSLog(@"Bubble tapped, show the view");
}

for Square

@implementation Square
...
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"square touched, lets hide the view");
}

After a Tap I see both NSLogs on the console

like image 825
perrohunter Avatar asked Oct 09 '12 06:10

perrohunter


1 Answers

Well , that is the problem . touchesBegan will get all the touches , including the ones taken by the gesture recognizer. You can try to set gestureRecognizer.cancelsTouchesInView = TRUE or use touchesBegan for your bubbles too.

Since it seems that you are making a game here , are you using some engine like cocos2D ? If that's the case , there are easier ways to accomplish what you want.

Hope this helps.

Cheers!

EDIT:

If you are using only gesture recognizers , the touch will not be sent to the next view in the hierarchy. I think this is what you want. If you decide to go with touches began I think you should do something like this:

//in the bubble view class

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event 
{
    if(theTouchLocation is inside your bubble)
    {
        do something with the touch
    }
    else
    {
        //send the touch to the next view in the hierarchy ( your large view )
       [super touchesBegan:touches withEvent:event];
       [[self nextResponder] touchesBegan:touches withEvent:event];
    }
}
like image 153
George Avatar answered Nov 10 '22 05:11

George