【问题标题】:How do I prevent taps on a subview from triggering a UITapGestureRecognizer on a parent view?如何防止点击子视图触发父视图上的 UITapGestureRecognizer?
【发布时间】:2016-03-31 02:05:16
【问题描述】:

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

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

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

【问题讨论】:

    标签: ios objective-c uitapgesturerecognizer


    【解决方案1】:

    假设您的parentView 有一个subView。你实现了下面的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;
        }
    }
    

    【讨论】:

    • 这对我来说似乎比批准的答案更好。阻止点击,而不是添加更多什么都不做的识别器。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢!即使在 Swift 4.0 中这也有效,这正是我正在寻找的一个简单的解决方案:)
    • 我已经更改了代码,出现了一个小错误(您不应该使用视图的框架,使用边界来获取子视图的当前框架)。
    【解决方案3】:

    AlertView 的 Swift 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)
        }
    }
    

    【讨论】:

      【解决方案4】:

      在斯威夫特中:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-26
        • 2012-12-15
        • 1970-01-01
        相关资源
        最近更新 更多