Search code examples
iosobjective-cuitextviewuigesturerecognizeruitextviewdelegate

UITextView double tap to edit


So I have a UITextView I'm using to make a moveable, editable label (My prior searches on SO showed this to apparently be the best option). I need to have the user double tap to enable editing and set it to become the first responder. I can't find a way to do this, and all my other searches have turned up either outdated answers or vague answers. Nothing I've tried seems to work. I've tried using the UITextViewDelegate to have it start editing as opposed to selecting text using textViewDidChangeSelection:, but it doesn't work until you change the current selection. I also tried using a custom UITapGestureRecognizer like so:

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[doubleTap setNumberOfTouchesRequired:1];
[newLabel addGestureRecognizer:doubleTap];

-(void)doubleTap:(UITapGestureRecognizer *)sender
{
    NSLog(@"Double tap detected");
    NSLog(@"Sender view of class %@", [[sender view] class]);
    UITextView *tappedView = (UITextView *)[sender view];
    [tappedView setEditable:YES];
    [tappedView becomeFirstResponder];
//    [tappedView setEditable:NO];
}

The double tap gesture is never called. I'm not sure why. Strangely, it also doesn't select text either while it's like that. It seems to just break double tap gestures. Is there a way to get rid of the standard double tap selection gesture, or to modify it? Should I subclass UITextView and, if so, what would I change?


Solution

  • Sublassing UITextView, I added this method to the .m file.

    -(BOOL)canBecomeFirstResponder
    {
        if (self.editable == YES){
            return YES;
        }
        else{
        return NO;
        }
    }
    

    In addition to this, I used

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

    This is the best way I found to solve my problem. I only wanted to allow double tapping to edit. I wanted no text selection, scrolling, etc to happen until it was double tapped. To futher finish this, you'll need a to use a UITextViewDelegate to turn textView.editable = NO

    -(void)textViewDidEndEditing:(UITextView *)textView
    {
        [textView setEditable:NO];
    }