【问题标题】:how to add double tap gesture to UITextView如何将双击手势添加到 UITextView
【发布时间】:2012-11-29 12:35:52
【问题描述】:

目前我想让 UITextView 有一个双击手势。 UITableView 似乎有自己的双击手势,当我们双击时,会选择一些文本。所以我想将这个默认的双击手势移除到我自己的手势识别器中。我尝试了很多方法,都失败了。似乎没有办法删除 UITextView 的默认识别器。我还想在这个 UITextView 上添加一个透明视图来执行双击事件,但是这个子视图会阻止 UITextView 上的其他手势。是否有一些方法可以将双击手势识别器添加到 UITextView?我真的希望有一个解决方法。

我仍然期待 iOS5 的解决方法 :)

【问题讨论】:

    标签: ios uitextview uitapgesturerecognizer


    【解决方案1】:

    还有许多其他手势识别器附加到文本视图。因为你似乎不需要它们。您可以删除它们。

    myTextView.gestureRecognizers = nil;
    

    在添加双击识别器之前。它有效。

    然后你可以添加

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mySelector)];
    tapRecognizer.numberOfTapsRequired = 2;
    tapRecognizer.numberOfTouchesRequired = 1;
    [myTextView addGestureRecognizer:tapRecognizer];
    

    【讨论】:

    • 我在iOS6下,这个方法在ios6之前是否有效,我不知道
    • 我知道这是一个老问题,但我自己也遇到了不同的解决方案。如果您还将 TextView 的可编辑属性设置为 NO 并将其子类化以将 canBecomeFirstResponder 设置为也自动返回 NO,则使用上述技术将起作用。
    【解决方案2】:

    我在iOS6上有解决方案,我们可以使用UIGestureRecognizerDelegate,并覆盖gestureRecognizerShouldBegin:和gestureRecognizer:shouldReceiveTouch:。在这两个方法中,我们可以检查手势是否为doubleTapGestureForZooming,如果不是返回NO,或者返回YES。这在 iOS6 中完美运行,但在 iOS5 中这两个委托方法尚未被调用,因此 iOS5 可能需要另一种解决方法。 最后,我得到了解决方法,我们可以覆盖 UITextView 的 addGestureRecognizer 方法来删​​除默认手势,希望这对其他人有帮助。

    PS:UITextView 的系统手势我们真的不能移除,我们甚至不能改变它们的属性。似乎当事件发生时,UItextview的所有手势都会重新添加。

    【讨论】:

      【解决方案3】:

      我知道这个问题很老了,但为了让未来的搜索者保持最新状态,我想我会添加另一个从 iOS 7 到 10 对我有用的解决方案。它基本上汇集了讨论的解决方案 here 和 @987654322 @ 但调整它们以使 UITextView 识别自定义双击。

      它通过继承UITextView 并覆盖addGestureRecognizer: 方法来实现这一点,以便将我们的自定义回调注入双击手势并配置单击手势以尊重新的双击钩子。

      我在 addGestureRecognizer: 中这样做是因为 UITextView 会根据其当前状态不断删除和添加手势,因此您必须不断将其重新设置。

      这段代码应该足以让某人开始:

      @interface MyCustomTextView ()
      
      /**
       *  we want to keep track of the current single-tap gesture so we can make sure
       *  it waits for a double-tap gesture to fail before firing
       */
      @property (weak, nonatomic) UITapGestureRecognizer *singleTap;
      
      /**
       *  we want to keep track of the current double-tap gesture so we can tell a single
       *  tap gesture to ignore this double-tap when the single tap gesture changes
       */
      @property (weak, nonatomic) UITapGestureRecognizer *doubleTap;
      
      @end
      
      
      @implementation MyCustomTextView
      
      /**
       *  this will fire when the text view is double-tapped
       *
       *  @param tgr
       */
      - (void)_handleTwoTaps:(UITapGestureRecognizer *)tgr
      {
          // ADD CODE HERE
      }
      
      /**
       *  the reason why I've overridden this methods is these gestures change quite a bit
       *  depending on the state of the UITextView, (eg, when in focus and out of focus)
       *  and so this provides a reliable way to make sure any new gestures get updated
       *  with custom overrides.
       *
       *  @param gestureRecognizer
       */
      - (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
      {
          [super addGestureRecognizer:gestureRecognizer];
          if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
              UITapGestureRecognizer *tgr = (UITapGestureRecognizer *)gestureRecognizer;
              if ([tgr numberOfTapsRequired] == 1 && [tgr numberOfTouchesRequired] == 1) {
                  self.singleTap = tgr;
                  if (self.doubleTap) {
                      [tgr requireGestureRecognizerToFail:self.doubleTap];
                  }
      
              } else if ([tgr numberOfTapsRequired] == 2 && [tgr numberOfTouchesRequired] == 1) {
                  [tgr addTarget:self action:@selector(_handleTwoTaps:)];
                  self.doubleTap = tgr;
                  if (self.singleTap) {
                      [self.singleTap requireGestureRecognizerToFail:tgr];
                  }
              }
          }
      }
      
      // NOTE: I'm not sure if this is needed but it's been there for years
      // and so I thought I would include it just in case
      - (void)removeGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
      {
          if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
              UITapGestureRecognizer *tgr = (UITapGestureRecognizer *)gestureRecognizer;
              if ([tgr numberOfTapsRequired] == 2 && [tgr numberOfTouchesRequired] == 1) {
                  [tgr removeTarget:self action:@selector(_handleTwoTaps:)];
              }
          }
          [super removeGestureRecognizer:gestureRecognizer];
      }
      
      @end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多