I know this question is old, but to keep it current for future searchers, I figured I would add another solution that has worked for me from iOS 7 through 10. It basically brings together the solutions discussed here and here but tweaks them to get the UITextView
to recognize the custom double tap.
It does this by subclassing the UITextView
and overriding the addGestureRecognizer:
method in order to inject our custom callback into the double-tap gesture and configure the single-tap gesture to respect the new double tap hook.
I do this in addGestureRecognizer:
because a UITextView
constantly deletes and adds gestures depending on its current state and so you constantly have to reset it back up.
This code should be enough to get someone started:
@interface MyCustomTextView ()
@property (weak, nonatomic) UITapGestureRecognizer *singleTap;
@property (weak, nonatomic) UITapGestureRecognizer *doubleTap;
@end
@implementation MyCustomTextView
- (void)_handleTwoTaps:(UITapGestureRecognizer *)tgr
{
}
- (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];
}
}
}
}
- (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