I have a textView which has a UITapGesture which has this method as a selector - (void)textTapped:(UITapGestureRecognizer *)recognizer
. When I tap a little below the last line of the textview or after my last character that displays it will invoke the method on the attributed text of my last character because it seems: layoutManager characterIndexForPoint:location
inTextContainer:textView.textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
returns the last character. I don't want it to use the last character in this case as I'd rather it not go into my conditional statement. I tried updating the logic so it would be characterIndex < textView.textStorage.length - 1
and that handled this case fine but if I tap on the last character then it doesn't call the function. Is there a way to prevent the last character from being returned when it's not tapped and just get the exact character as tapped or some other way to prevent invoking the method.
- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
UITextView *textView = (UITextView *)recognizer.view;
// Location of the tap in text-container coordinates
NSLayoutManager *layoutManager = textView.layoutManager;
CGPoint location = [recognizer locationInView:textView];
location.x -= textView.textContainerInset.left;
location.y -= textView.textContainerInset.top;
// Find the character that's been tapped on
NSUInteger characterIndex;
characterIndex = [layoutManager characterIndexForPoint:location
inTextContainer:textView.textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
if (characterIndex < textView.textStorage.length) {
NSRange range;
id value = [textView.attributedText attribute:@"myCustomTag" atIndex:characterIndex effectiveRange:&range];
// Handle as required...
NSLog(@"%@, %d, %d", value, range.location, range.length);
}
}
I think instead of using characterIndexForPoint
you need to use glyphIndexForPoint
documentation for which you can found here. Apple Documentation
Now in the documentation it clearly tells you what steps to follow after finding the glyph and I'll quote from the paragraph from the documentation:
If no glyph is under point, the nearest glyph is returned, where nearest is defined according to the requirements of selection by mouse. Clients who wish to determine whether the the point actually lies within the bounds of the glyph returned should follow this with a call to
boundingRectForGlyphRange:inTextContainer:
and test whether the point falls in the rectangle returned by that method. If partialFraction is non-NULL, it returns by reference the fraction of the distance between the location of the glyph returned and the location of the next glyph.