UITapGestureRecognizer not triggered in deep view hiearchy
Asked Answered
T

1

0

I have placed a UIGestureRecognizer deep within my uiview hierarchy but it is not being trigger. Here is a general map of the views:

UIScrollView > UIView > UIView > UIView > UIView

The last view has the gesture recognizer:

- (id)initWithFrame:(CGRect)frame {    
    self = [super initWithFrame:frame];

    if (self) {
        self.userInteractionEnabled = TRUE;

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
        [self addGestureRecognizer:tap];
        [tap release];
    }  

    return self;
}

- (void)tap:(UIGestureRecognizer *)recognizer {
    NSLog(@"tap");
}

I am setting the canCancelContentTouches of the scrollview to allow gestures to propagate through.

When I moved the view with the gesture to directly underneath the scrollview it works. Can someone explain why it does not work in a deep hierarchy?

Thanks!

Taffy answered 29/7, 2011 at 10:45 Comment(0)
P
0

In such a hierarchy the point you touch must be in within the views frame and all parent frames. The responder chain starts at the scrollview, and if the touch is outside of the scrollview it stops there. Then it checks the direct children of the scrollview and so on.

If that's not the case i suggest writing your own hittest function to check if the last frame is hit and return it then.

Proa answered 29/7, 2011 at 12:3 Comment(3)
Thanks for the response. If I understand what you're saying correctly, then if all views are visible that would mean they are in all parent frames. They are all visible on the screen.Taffy
Views on iOS don't clip their subviews, so make sure their actual frames and bounds are as big as you expect (you could debug it quickly by setting all of the views' clipsToBounds property to YES and seeing what comes out). This kind of thing has bitten me many times.Treen
If a touch hits a view is determined by the hittest function. it is called in all children. if the view is not userInteractionEnabled or the hit is out of its bounds it will return false immediately. then each subview will call the hittest in all of his own subviews.. until a hittest returns the view that was hit. you can write your own hittest to change this default behavior.Proa

© 2022 - 2024 — McMap. All rights reserved.