【问题标题】:How to reliably find correct view for UIGestureRecognizer?如何可靠地找到 UIGestureRecognizer 的正确视图?
【发布时间】:2011-06-15 17:32:42
【问题描述】:

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

  • 红色有一个UISwipeGestureRecognizer
  • 格林拥有UITapGestureRecognizer
  • 蓝色没有识别器。

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

轻按绿色的隐藏部分不会触发其识别器(红色会阻止它)。

这就是问题所在:我希望 Green 触发。我该怎么做?

在实践中,视图可以是任意顺序,任意数量,并且是彼此的子视图等。但问题是一样的:

我怎样才能可靠地找到可以处理手势(点击或滑动)的最上面的视图?


我尝试使用下面的代码。它巧妙地遍历所有视图,但它失败了,因为它不知道该事件是滑动还是点击的一部分。所以该方法总是返回红色视图。如果我从 Red 中删除 swipe-recognizer,则代码可以正常工作。

- (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;
 }

【问题讨论】:

    标签: iphone cocoa-touch uiview uigesturerecognizer


    【解决方案1】:

    将手势识别器添加到这些视图的另一种方法是将手势识别器添加到父视图并使用委托方法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;
    }
    

    【讨论】:

    • 是的,关键是(如您所说)将所有识别器添加到超级视图并从那里处理它。我的层次结构非常复杂(想想多边形汤),但这个想法很有效。
    【解决方案2】:

    一种可能的解决方案是将点击手势识别器添加到顶部红色视图,然后每当您点击时,检查点击点是否与绿色视图相交。如果是这样,请将点击转发到该视图。如果没有,请忽略水龙头。

    【讨论】:

      【解决方案3】:

      我的解决方案是:

      -(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer {
          CGPoint touchPoint = [tapGestureRecognizer locationInView:viewUnderTest];
          if ([viewUnderTest pointInside:touchPoint withEvent:nil]) {
              NSLog(@"Hit done in view under test");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-24
        • 2011-05-03
        • 2013-12-17
        • 2014-01-31
        • 1970-01-01
        • 2011-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多