Detecting tapped character. UITextView characterRangeAtPoint always returns nil
Asked Answered
E

4

5

I'm trying to determine, which particular character in UITextView has been tapped. I tried to use characterRangeAtPoint: method. But it always returns nil, wherever in the UITextView I tap. I even wrote and run the following piece of code:

for (int x = 0; x<1000; x++) {
    pos.x = x;
    for (int y = 0; y<1000; y++) {
        pos.y = y;
        UITextRange * range = [textView characterRangeAtPoint:pos];
        if (range!=nil) {
            NSLog(@"x: %f, y: %f", pos.x, pos.y);
        }
    }
}

Well, it never reaches the NSLog string. What am I doing wrong?

Expeditionary answered 20/9, 2013 at 20:58 Comment(0)
I
8

This is an iOS 7 bug. characterRangeAtPoint: always returns nil, unless some text has been selected at least once beforehand.

As a workaround, you could call setSelectedRange: or setSelectedTextRange: beforehand, but then the textView would highlight your selection. I came up with the following solution:

[textView select:textView];
[textView setSelectedTextRange:nil];

After you call these two methods, characterRangeAtPoint: will start working as expected.

Note that you just need to call this once after textView has been initialized.

EDIT: my answer was edited from "unless some text has been selected beforehand" to "unless some text is currently selected". This is wrong: text doesn't need to be currently selected, it just has to be selected once. All subsequent calls to setSelectedRange: will then be successful, as stated in my note. Edited back for further clarity.

Issiah answered 2/11, 2013 at 22:40 Comment(0)
P
5

Your UITextView must be selectable. In storyboard, check the "Selectable" checkbox.

In code,

textView.selectable = YES;

This is also required for the -closestPositionToPoint: method on UITextView.

Pragmaticism answered 10/3, 2014 at 19:39 Comment(0)
M
0

Use shouldChangeCharactersInRange method instead of characterRangeAtPoint.

And use your If condition inplace of loop statement.

Mycobacterium answered 21/9, 2013 at 5:57 Comment(1)
Sorry, I don't see, how shouldChangeCharactersInRange could help me find the dependence between touch coordingates and character ranges.Expeditionary
T
0

Is your TextView user-editable? If YES, then try the texViewDidChangeSelection method. It is invoked every time the caret(cursor) is moved in a textView. Then get the cursor position by textView.selectedRange.location to point to the index, of the caret.

My assumption here is that you want the location of the character with respect to the number of character, and not co-ordinates in 2D.

Trailblazer answered 21/9, 2013 at 6:3 Comment(1)
No, my intention is to override the native selection behaviour. So I need mapping from CGPoint to UITextRange (or NSRange, whatever).Expeditionary

© 2022 - 2024 — McMap. All rights reserved.