如何将双击手势添加到UITextView

4

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

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

3个回答

13

文本视图中还连接了其他手势识别器。由于似乎您不需要它们,因此可以将其删除。

myTextView.gestureRecognizers = nil;

在添加您的双击手势识别器之前。它有效。

然后您可以添加

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

我使用的是iOS6,不确定这个方法在iOS6之前是否有效。 - Charlesjean
我知道这是一个老问题,但我自己找到了另一种解决方案。如果您还将TextView的可编辑属性设置为NO并对其进行子类化以自动返回NO,则使用上述技术将起作用。 - Pete.Mertz

2
我有一个iOS6的解决方案,我们可以使用UIGestureRecognizerDelegate,并重写gestureRecognizerShouldBegin:和gestureRecognizer:shouldReceiveTouch:这两个方法。在这两个方法中,我们可以检查手势是否为doubleTapGestureForZooming,如果不是则返回NO,否则返回YES。这在iOS6中完美运行,但在iOS5中这两个委托方法没有被调用,所以iOS5可能需要另一种解决方法。 最后,我找到了解决方法,我们可以重写UITextView的addGestureRecognizer方法来删除默认手势,希望这能帮助其他人。
PS:我们真的无法删除UITextView的系统手势,甚至无法更改它们的属性。似乎当事件发生时,UITextview的所有手势都会再次添加。

1
我知道这个问题很老,但为了让未来的搜索者能够找到最新的解决方案,我想添加另一个解决方案,该方案从iOS 7到10都适用于我。它基本上将herehere中讨论的解决方案结合起来,但对它们进行了调整,以使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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接