【问题标题】:Creating a UIView that captures taps, but is transparent to all other gestures创建一个捕捉点击但对所有其他手势透明的 UIView
【发布时间】:2012-11-16 08:28:09
【问题描述】:

我想实现以下目标。

场景:iOS 键盘在用户输入特定文本字段时显示在屏幕上。用户可以点击键盘和文本字段之外的任何地方来关闭键盘(无需激活任何可见的按钮)。此外,用户可以拖动到键盘外并观察一些可滚动视图排列的正常拖动行为。

从概念上讲,我在大部分屏幕上放置了一个“封面”UIView,其行为如下:

  1. 如果用户点击封面,我会捕捉该点击(这样我就可以关闭键盘)。这很容易通过在UIView 子类中拦截触摸事件或使用轻击手势识别器来实现。

  2. 如果用户在封面上拖动,则封面忽略向前这些触摸;这些被下面的层接收,就像没有覆盖一样。

所以:用户应该能够滚动封面下方的内容,但不能点击封面下方的内容。在键盘和文本字段的“外部”轻按应该会关闭键盘(和覆盖),但不应激活任何东西。

我怎样才能做到这一点?

【问题讨论】:

  • 您必须考虑实现触摸委托方法并将触摸传递给其背后的视图以进行滑动。 - (void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*)event{ [otherView touchesBegan:touches withEvent:event]; }另一种方式是实现,UIPanGestureRecognizer,设置cancelsTouchesInView = YES为UIPanGestureRecognizer *gr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan)]; [gr setCancelsTouchesInView:YES]; [myButton addGestureRecognizer:gr]; [gr release];
  • @mjh,你找到解决办法了吗?

标签: ios xcode user-interface uiscrollview gestures


【解决方案1】:

以通常的方式添加点击手势:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.view addGestureRecognizer:tapGesture];

但您可能正在寻找的是:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {    
        return YES;
    }

文档说:当通过gestureRecognizer 或otherGestureRecognizer 识别手势会阻止其他手势识别器识别其手势时调用此方法。 (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/index.html#//apple_ref/occ/intf/UIGestureRecognizerDelegate)

这样,您可以确定它是完全透明的,并且没有什么会阻止您的识别器被调用。

【讨论】:

    【解决方案2】:

    转发它收到的所有触摸的自定义视图:

    class CustomView: UIView {
    
        override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
    
            var hitView = super.hitTest(point, withEvent: event)
    
            if hitView == self {
                return nil
            }
    
            return hitView
        }    
    }
    

    从那里你可以通过不同的方式来使用点击手势。观察 UIEvent 的触摸,或使用手势识别器。

    【讨论】:

      【解决方案3】:

      1:在视图中添加点击手势识别器:

          //Adding tap gesture
          UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
          tapGesture.numberOfTapsRequired = 1;
          [self.view addGestureRecognizer:tapGesture];
      

      2:在handleTapGesture中你resignFirstResponder的键盘

      - (void)handleTapGesture:(UITapGestureRecognizer *)sender {
          if (sender.state == UIGestureRecognizerStateRecognized) {
             //Resign first responder for keyboard here
          }
      }
      

      对上面的答案进行了详细说明。 UIGestureRecognizerStateRecognized 确保它是被识别的单个选项卡事件。

      这是你追求的功能吗?

      【讨论】:

      • 他的问题是“如果用户在封面上拖动,那么封面会忽略所有触摸;这些触摸会被下面的图层接收,就像没有封面一样。”。他已经想出了如何检测触摸。
      • 如果UIView 能够识别点击,那么它的.userInteractionEnabled 必须是YES,因此它会吃掉所有的触摸事件,防止拖动被下面的任何东西识别。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多