Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView with clickable links but no text highlighting

I have a UITextView displaying non-editable text. I want the text to automatically parse links, phone numbers, etc for the user, and for those to be clickable.

I don't want the user to be able to highlight text, though, because I want to override those long press and double-tap interactions to do something different.

In order for links to be parsed in iOS7, the Selectable switch needs to be turned on for the UITextView, but Selectable also enables highlighting, which I don't want.

I tried overriding the LongPress gesture to prevent highlighting, but that seems to have disabled ordinary taps on links as well...

for (UIGestureRecognizer *recognizer in cell.messageTextView.gestureRecognizers) {
    if ([recognizer isKindOfClass:[UILongPressGestureRecognizer class]]){
        recognizer.enabled = NO;
    }
    if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]){
        recognizer.enabled = YES;
    }
}

There are lots of similar threads out there but none seem to address this specific question of links enabled, text not highlightable.

like image 466
Trespassers W Avatar asked May 15 '14 23:05

Trespassers W


3 Answers

I am working on the exact same problem and the best I could do was to instantly clear the selection as soon as it is made by adding the following to the UITextView's delegate:

- (void)textViewDidChangeSelection:(UITextView *)textView {
    if(!NSEqualRanges(textView.selectedRange, NSMakeRange(0, 0))) {
        textView.selectedRange = NSMakeRange(0, 0);
    }
}

Note the check to prevent recursion. This pretty much addresses the issue because only selection is disabled -- links will still work.

Another tangential issue is that the text view will still become first responder, which you can fix by setting your desired first responder after setting the selected range.

Note: the only visual oddity that remains is that press-and-hold brings up the magnifying glass.

like image 85
blushmessenger Avatar answered Nov 15 '22 13:11

blushmessenger


I'm not sure if this works for your particular case, but I had a similar case where I needed the textview links to be clickable but did not want text selection to occur and I was using the textview to present data in a CollectionViewCell.

I simply had to override -canBecomeFirstResponder and return NO.

@interface MYTextView : UITextView
@end

@implementation MYTextView

- (BOOL)canBecomeFirstResponder {
    return NO;
}

@end
like image 33
lramirez135 Avatar answered Nov 15 '22 12:11

lramirez135


As I wrote on the other post, there is another solution I found after few tests.

If you want links active and you don't want selection enabled, you need to edit gestureRecognizers.

For example - there are 3 LongPressGestureRecognizers. One for click on link (minimumPressDuration = 0.12), second for zoom in editable mode (minimumPressDuration = 0.5), third for selection (minimumPressDuration = 0.8). This solution removes LongPressGestureRecognizer for selecting and second for zooming in editing mode.

NSArray *textViewGestureRecognizers = self.captionTextView.gestureRecognizers;
NSMutableArray *mutableArrayOfGestureRecognizers = [[NSMutableArray alloc] init];
for (UIGestureRecognizer *gestureRecognizer in textViewGestureRecognizers) {
    if (![gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
        [mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
    } else {
        UILongPressGestureRecognizer *longPressGestureRecognizer = (UILongPressGestureRecognizer *)gestureRecognizer;
        if (longPressGestureRecognizer.minimumPressDuration < 0.3) {
            [mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
        }
    }
}
self.captionTextView.gestureRecognizers = mutableArrayOfGestureRecognizers;

Tested on iOS 9, but it should work on all versions (iOS 7, 8, 9). I hope it helps! :)

like image 21
Jakub Kašpar Avatar answered Nov 15 '22 13:11

Jakub Kašpar