Search code examples
iphoneiosios6uitextviewios7

In IOS 7, UITextView offsetFromPosition: toPosition: always return 0 with arguments of UITextPositions returned from UITextView characterRangeAtPoint


I was trying to use UITextView characterRangeAtPoint in my code to get UITextRanges at some CGPoints within the textview. And then I used the UITextPositions from those UITextRanges as arguments and used UITextView offsetFromPosition: toPosition: to get the offset. It worked well in iOS 6. But when I tried it in iOS 7, it always returned me offset 0 no matter what CGPoint I tried within the textview.

Here is the code:

// init the textview
textview = [[UITextView alloc] initWithFrame:CGRectMake(10, 50, 300, 500)];
textview.backgroundColor = [UIColor whiteColor];
[self.view addSubview:textview];

// load the txt file for testing  
NSError *error;
NSString *content = [[NSString alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"] encoding:NSUTF8StringEncoding error:&error];
if (error) {
    NSLog(@"load string error:%@", [error localizedFailureReason]);
    return;
}

// set the text and font
textview.text = content;
UIFont *font = [UIFont systemFontOfSize:18];
textview.font = font;

// get text range at point (100, 100) and string offset from the beginning to this point 
UITextRange *textrange = [textview characterRangeAtPoint: CGPointMake(100, 100)];
NSInteger offset = [textview offsetFromPosition:textview.beginningOfDocument toPosition:textrange.start];
NSLog(@"offset = %d", offset);

The offset it returned was always 0. In order to test if it was because of UITextView offsetFromPosition: toPosition:, I tried the following code:

NSInteger offset1 = [textview offsetFromPosition:textview.beginningOfDocument toPosition:textview.endOfDocument];
NSLog(@"offset1 = %d", offset1);

it gave me offset1 = 5264, which was correct according to the test.txt I used. So the problem is the UITextRange returned from textview characterRangeAtPoint. It seemed that in IOS 7 the characterRangeAtPoint didn't return me the correct text range at the given CGPoint. So textview offsetFromPosition: toPosition: couldn't return the correct offset.

But I used the same code in IOS 6 and it worked very well. I also checked the reference of characterRangeAtPoint, but found no useful information.

Does anyone know what happened with characterRangeAtPoint in IOS 7? In order to make it functional as it was in IOS 6, what should I do?


Solution

  • I met the same issue. And I found that characterRangeAtPoint wouldn't return a value unless text has been changed or selected at least once in the TextView in IOS 7. I can't make this function to work properly so I had to avoid to use it(I tried to set setContentInset as well but no luck). And here is my workaround. I believe you can make something similar to fit your situation.

    // get the beginning position of the current line.
    NSRange pos = [textView.text rangeOfString:@"\n" options:NSBackwardsSearch range:NSMakeRange(0,textView.selectedRange.location)];
    if (pos.location == NSNotFound) pos.location = 0; // if the text has only one line.
    NSLog(@"pos = %d",pos.location);