Reputation: 1395
I am trying to segue upon taps on specific words in a UITextView (not editable) - imagine hashtags or mentions in Instagram or Twitter mobile apps.
This post helped me understand how to identify taps on specific words inside a UITextView:
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(printWordSelected:)];
[self.textView addGestureRecognizer:tap];
}
- (IBAction)printWordSelected:(id)sender
{
NSLog(@"Clicked");
CGPoint pos = [sender locationInView:self.textView];
NSLog(@"Tap Gesture Coordinates: %.2f %.2f", pos.x, pos.y);
//get location in text from textposition at point
UITextPosition *tapPos = [self.textView closestPositionToPoint:pos];
//fetch the word at this position (or nil, if not available)
UITextRange * wr = [self.textView.tokenizer rangeEnclosingPosition:tapPos
withGranularity:UITextGranularityWord
inDirection:UITextLayoutDirectionRight];
NSLog(@"WORD: %@", [self.textView textInRange:wr]);
}
Unfortunately, this approach is not bullet proof and report taps on white space in the end of the line as taps on words in the beginning of the next line.
Obviously this is a result of word wrapping in UITextView that sometimes moves words to the beginning of the next line.
Upvotes: 2
Views: 941
Reputation: 53830
A simple solution is to only return the word if it's the same in both directions (left and right). There is one limitation with this approach, however. You won't be able to select single character words.
- (IBAction)printWordSelected:(id)sender
{
CGPoint pos = [sender locationInView:self.textView];
//get location in text from textposition at point
UITextPosition *tapPos = [self.textView closestPositionToPoint:pos];
//fetch the word at this position (or nil, if not available)
UITextRange * wr = [self.textView.tokenizer rangeEnclosingPosition:tapPos
withGranularity:UITextGranularityWord
inDirection:UITextLayoutDirectionRight];
//fetch the word at this position (or nil, if not available)
UITextRange * wl = [self.textView.tokenizer rangeEnclosingPosition:tapPos
withGranularity:UITextGranularityWord
inDirection:UITextLayoutDirectionLeft];
if ([wr isEqual:wl]) {
NSLog(@"WORD: %@", [self.textView textInRange:wr]);
}
}
Upvotes: 2