Question

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?

Was it helpful?

Solution 2

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];
}

OTHER TIPS

I found a neat solution, with less code (Swift 4.2):

Create a Custom UITextView Class and in it write this

    override var canBecomeFirstResponder: Bool {
    if self.isEditable {
        return true
    } else {
        self.isEditable = true
        return false
    }

Then in viewDidLoad() write the following (or deselect 'Editable' under behaviour in the storyboard editor)

myTextView.isEditable = false

Then simply put the same code somewhere when you're finished editing the text - eg. textViewDidEndEditing(_ textView: UITextView)

myTextView.isEditable = false

When the view loads, the textView is not editable and all data detectors work. A second tap then allows it to be edited (and disables the data detectors).

As soon as you exit the textView, it's set to not editable again and the data detectors work.

All this without any gesture recognisers! :-D

You should set the target of the Gesture Recognizer as the textfield.

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:textField action:@selector(doubleTap:)];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top