0

I've set a UITapGestureRecognizer on a view. Only specific areas within the view need to trigger the view's behavior. I do that by checking whether the exact location of the touch is on actual actionable areas in the view. In cases where the touch is not in these areas, I'd like the tap to propagate upwards in the view hierarchy.

I've tried to use the gesture delegate: shouldReceive touch, and test there if the touch is relevant to the view, but I cannot perform the action there, as it fires on touch, not on tap. I could just perform the relevancy test in shouldReceive, and only if the tap action handler gets called perform the action, but I find it awkward. Is there a more elegant way to tell iOS that my gesture recognizer decided not to consume the tap?

jazzgil
  • 2,250
  • 2
  • 19
  • 20
  • can you share some related code? Are the _specific areas_ where the tap gesture should be triggered, different type of view as compared to others? – ystack Feb 18 '17 at 21:19
  • In practice, the view I work on is a UITextView with an attributedString, where only parts of it are marked with a custom tap action. So in my action I first test if the tap touches any of those areas, and if not, do nothing (preferably not consume the tap). – jazzgil Feb 18 '17 at 21:33
  • Woah! If there were multliple views involved using `gestureRecognizer: shouldReceiveRouch` would have been right way. But with attributed strings, for non-trivial use-cases, you should rely on Text Kit. Without looking at any code, I can only suggest to examine this particular answer, will be helpful: http://stackoverflow.com/a/28519273/3339346 – ystack Feb 18 '17 at 21:42
  • Thanks @ystack. Fortunately, my attributedString tap handler works fine, and correctly detects the location of the taps. The only issue is how to tell iOS when my handler found the tap not relevant to the text. Your link doesn't go into that. – jazzgil Feb 18 '17 at 21:49
  • Can you not use a simple `if-else` around the gesture location point in view calculations to achieve this? – ystack Feb 18 '17 at 21:55
  • Indeed I do if-else in gesture handler. But the handler doesn't return any value to tell iOS whether to pass on the tap to parent views... – jazzgil Feb 18 '17 at 22:09

1 Answers1

0

Based on our discussion, you can evaluate using a combination of the if-else check in attributedString touch handler & gestureRecognizer:shouldReceiveTouch:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    if ([touch.view isDescendantOfView:interestingView]) {
        return NO;
    }
    return YES;       
}

Hope this helps.
If not, then again, I'll reiterate, it would be better you could share some related code.

ystack
  • 1,785
  • 12
  • 23
  • As I explained - this is what I already have in place, but find it cumbersome and awkward to split the test part and the action triggering. I'm looking for a solution within the gesture action handler of the tap itself. – jazzgil Feb 18 '17 at 22:40
  • Yeah, I know _^this_ can get ugly. Maybe, you could consider breaking away your views from the hierarchy. Don't create a _parent-child_ view hierarchy between views who need to handle gestures differently. OR, have a gesture handling _router_, which determines the location of gesture & invokes independent gesture handlers who each have _no_ dependency, whatsoever, on view for any data. – ystack Feb 18 '17 at 22:47