Search code examples
iphoneiosobjective-cuikitcore-text

Detecting tapped character. UITextView characterRangeAtPoint always returns nil


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?


Solution

  • 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.