Question

I have a UITextView which is hooked up to a pan gesture recognizer. When I drag my finger over the text view, I use the characterIndexForPoint method to figure out which character my finger is over & then highlight the text at that point.

In some cases where the text in the view has line breaks, this method seems to return different results even though I'm passing in the same parameters. The touched method is called twice in a row, and once the charIndex is 167, and then next it's 270.

I have checked the text view's AttributedString and it is the same font size in both cases.

- (IBAction)touched:(UIPanGestureRecognizer *)sender {
    if (self.txtView.isFirstResponder) {
        return;
    }
    if (sender.state == UIGestureRecognizerStateChanged) {

        CGPoint touchPoint = [sender locationInView:self.txtView];
        NSUInteger charIndex = [self.txtView.layoutManager
                     characterIndexForPoint:touchPoint
                            inTextContainer:self.txtView.textContainer
   fractionOfDistanceBetweenInsertionPoints:0];
 ...

Is this a known bug? Am I doing something wrong?

Was it helpful?

Solution

One thing that you are doing wrong is that fractionOfDistanceBetweenInsertionPoints: should not be zero. It is a result parameter, so it should be the address of a CGFloat or NULL if you don't care.

     CGPoint touchPoint = [sender locationInView:self.txtView];
     CGFloat fraction = 0;
     NSUInteger charIndex = [self.txtView.layoutManager
                  characterIndexForPoint:touchPoint
                         inTextContainer:self.txtView.textContainer
fractionOfDistanceBetweenInsertionPoints:&fraction];

You may not be interested in the fractionOfDistanceBetweenInsertionPoints: later, but it may be able to help you diagnose this issue. The point you are passing in may be ambiguous and it will help you to see that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top