6

I have a UIView called view1. view1 has a subview called subview. I added UITapGestureRecognizer to subview as follow:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
[subview addGestureRecognizer:recognizer];

If I tapped an area overlapped between subview and view1 then the handleTap method got called. But if I tapped an area on the subview that was outside view1, then handleTap never got called. Is this behavior right? If not, any suggestion to what should I check for?

btw: The UIPanGestureRecognizer works fine. It does not exhibit the behavior mentioned above.

enter image description here

user523234
  • 14,323
  • 10
  • 62
  • 102

3 Answers3

2

That is the default behaviour of UIView, the subview should be inside parent view bounds. If you want something different is better you create a custom subclass of the top view and override (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Andrea
  • 26,120
  • 10
  • 85
  • 131
1

You need to customize the parent view and change the way it handles touches. See this question for more details.

Community
  • 1
  • 1
Jiri
  • 2,206
  • 1
  • 22
  • 19
0

I've found the answers talking about overriding pointInside:withEvent: to be lacking detail on explanation or implementation. In the original question, when the user taps in the black, unlabeled area/view (we'll call it view2), the event framework will only trigger hitTest:withEvent: for the main window down through the view2 (and its immediate subviews), and will never hit it for view1 because the point tested for in pointInside:point is outside of the bounds of view1's frame. In order to get subview1 to register the gesture, you should override view2's implementation of hitTest:withEvent to include a check for subview's pointInside:point

//This presumes view2 has a reference to view1 (since they're nested in the example).
//In scenarios where you don't have access, you'd need to implement this
//in a higher level in the view hierachy

//In view2
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        let ptRelativeToSubviewBounds = convert(point, to: view1.subview)
        if view1.subview.point(inside:ptRelativeToSubviewBounds, with:event){
            return view1.subview
        }
        else{
            return super.hitTest(point, with: event)
        }
David
  • 95
  • 1
  • 7