如何防止子视图上的点击在父视图上触发UITapGestureRecognizer?

时间:2016-03-31 02:05:17

标签: ios objective-c uitapgesturerecognizer

我在视图中添加了点击识别器:

   UITapGestureRecognizer* tgr = [[UITapGestureRecognizer alloc]
      initWithTarget:self action:@selector( onTap )];
   [view addGestureRecognizer: tgr];

问题是点击view子视图会触发onTap。我该如何预防?

4 个答案:

答案 0 :(得分:4)

假设您的parentViewsubView。您实现了以下UIGestureRecognizerDelegate方法,如果触摸位于subView的范围内,则返回no。

tgr.delegate = self;

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    CGPoint locationInView = [touch locationInView:self.parentView];
    if (CGRectContainsPoint(self.subView.frame, locationInView) ) {
        return NO;
    } else {
        return YES;
    }
}

答案 1 :(得分:1)

将子视图添加到视图的背景中,并将点击手势识别器附加到子视图:

UIView* subview = [[UIView alloc] initWithFrame:view.frame];
subview.backgroundColor = [UIColor clearColor];//or view.backgroundColor
[view addSubview:subview];
[view sendSubviewToBack:subview];
[subview addGestureRecognizer:tapRecognizer];

答案 2 :(得分:0)

迅速获得AlertView的4.2答案

添加手势识别器并设置委托:

let backgroundViewTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismiss))
backgroundViewTapGesture.delegate = self     
self.backgroundView.addGestureRecognizer(backgroundViewTapGesture)
self.backgroundViewTapGesture = backgroundViewTapGesture

然后添加扩展名以处理点击

extension AlertView: UIGestureRecognizerDelegate {

    // Only handle this for the background tap gesture
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        guard gestureRecognizer == backgroundViewTapGesture, let backgroundView = gestureRecognizer.view, let alertView = self.alertContentView else {
            return true
        }

        let touchLocation = touch.location(in: backgroundView)
        return !alertView.frame.contains(touchLocation)
    }
}

答案 3 :(得分:0)

在Swift中:

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    let locationInView = touch.location(in: mainView)
    if debugOptionsView.isHidden {
        return true
    }
    return !debugOptionsView.frame.contains(locationInView)
}