如何可靠地找到UIGestureRecognizer的正确视图?

Mar*_*man 17 iphone cocoa-touch uiview uigesturerecognizer

我有一堆UIViews,如下图所示.红色/粉红色(半透明)视图位于其他视图之上.

  • 红有一个UISwipeGestureRecognizer.
  • 格林有一个UITapGestureRecognizer.
  • 蓝没有识别器.

在此输入图像描述

点击绿色的可见(左下)部分会触发其识别器.

点击绿色的隐藏部分不会触发其识别器(红色阻止它).

这就是问题:我希望Green能够触发.我怎样才能做到这一点?

在实践中,视图可以是任何顺序,任何数字和彼此的子视图等.但问题是相同的:

如何可靠地找到可以处理手势的最上面的视图(点击或滑动)?


我试过下面的代码.它整齐地遍历所有视图,但它失败了,因为它无法知道事件是否是滑动或点击的一部分.因此该方法始终返回红色视图.如果我从Red中删除滑动识别器,则代码可以正常工作.

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self)
    {
        if (self.hasASwipeRecognizer)
            return self;  // What if this was a tap?
        if (self.hasATapRecognizer)
            return self; 
        else
            return nil;
    }
    else
         return hitView;
 }
Run Code Online (Sandbox Code Playgroud)

Dee*_*olu 17

将手势识别器添加到这些视图的替代方法是将手势识别器添加到父视图并使用委托方法gestureRecognizer:shouldReceiveTouch:方法适当地处理用例.

确定特定识别器是否应该接收触摸并返回YES.例如,如果通过的手势识别器是滑动识别器,则检查触摸点是否在绿色视图内并返回YES.NO否则返回.

如果有类似的手势识别器,那么我建议你保留一个参考并验证它.

用法

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    CGPoint pointInView = [touch locationInView:gestureRecognizer.view];

    if ( [gestureRecognizer isMemberOfClass:[UITapGestureRecognizer class]] 
        && CGRectContainsPoint(self.blueView.frame, pointInView) ) {
        return YES;
    } 

    if ( [gestureRecognizer isMemberOfClass:[UISwipeGestureRecognizer class]] 
        && CGRectContainsPoint(self.greenView.frame, pointInView) ) {
        return YES;
    }

    return NO;
}
Run Code Online (Sandbox Code Playgroud)