如何向UITextView添加双击手势

时间:2012-11-29 12:35:52

标签: ios uitextview uitapgesturerecognizer

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

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

3 个答案:

答案 0 :(得分:13)

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

myTextView.gestureRecognizers = nil;

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

然后你可以添加

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

答案 1 :(得分:2)

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

PS:我们真的无法删除UITextView的系统手势,我们甚至无法改变它们的属性。事件发生时,UItextview的所有手势都会再次添加。

答案 2 :(得分: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