如何可靠地找到正确的视图UIGestureRecognizer? [英] How to reliably find correct view for UIGestureRecognizer?

查看:126
本文介绍了如何可靠地找到正确的视图UIGestureRecognizer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆UIViews如下图所示。




  • 红色有一个 UISwipeGestureRecognizer

  • 绿色作为 UITapGestureRecognizer

  • 蓝色没有识别器。




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



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



这就是问题:我要绿色触发。



在实践中,视图可以是任何顺序,任何数字和彼此的子视图等等。但问题是一样的: / p>

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






我试过下面的代码。它整齐地遍历所有视图,但它失败,因为它不知道事件是否是滑动或水龙头的一部分。所以该方法总是返回红色视图。如果我从红色删除刷卡识别器,代码工作正常。

   - (UIView *)hitTest: withEvent:(UIEvent *)event 
{
UIView * hitView = [super hitTest:point withEvent:event];
if(hitView == self)
{
if(self.hasASwipeRecognizer)
return self; //如果这是一个水龙头怎么办?
if(self.hasATapRecognizer)
return self;
else
return nil;
}
else
return hitView;
}


解决方案

这些视图的识别器将是添加手势识别器到父视图,并使用委托方法 gestureRecognizer:shouldReceiveTouch:方法来处理用例。



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



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



使用

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


I have a bunch of UIViews like in the image below. The red/pink (semi-transparent) view is on top of the others.

  • Red has a UISwipeGestureRecognizer.
  • Green has as a UITapGestureRecognizer.
  • Blue has no recognizer.

A tap on the visible (bottom-left) part of Green trigger its recognizer.

A tap on the hidden parts of Green does not trigger its recognizer (Red blocks it).

That's the problem: I want Green to trigger. How can I do this?

In practice, the views may be in any order, any number and be subviews of each others etc. But the problem is the same:

How can I reliably find the uppermost view that can handle the gesture (tap or swipe)?


I tried with the code below. It neatly traverses all views, but it fails since it cannot know if the event is part of a swipe or a tap. So the method always returns the red view. If I remove the swipe-recognizer from Red, the code works correctly.

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

解决方案

An alternative to adding the gesture recognizer to these views would be to add the gesture recognizers to the parent view and handle the use cases appropriately using the delegate method gestureRecognizer:shouldReceiveTouch: method.

Identify whether the particular recognizer should receive the touch and return YES. For example, if the gesture recognizer passed is a swipe recognizer then check if the touch point is within the green view and return YES. Return NO otherwise.

If there are similar gesture recognizers then I suggest that you keep a reference and verify against it.

Usage

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

这篇关于如何可靠地找到正确的视图UIGestureRecognizer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆