UITextView -scrollRangeToVisible: wasn't working for me either. I have a UITextView and I'm trying to have it scroll to particular words. In my case I set the scrollEnabled property to NO on the UITextView because I need user scrolling to be disabled. For me the workaround was to set the scrollEnabled property back to YES and set the userInteractionEnabled property to NO. -scrollRangeToVisible: then started working but only sometimes. I had to change the text layout to TextKit1 as mentioned by @alexschecha to get the -scrollRangeToVisible: method to work properly.
Unlike -setContentOffset: the -scrollRangeToVisible: method will only work if the scrollEnabled property is YES it seems and it will only work reliably under TextKit1 as far as I can tell.
There is still a limitation though. I'd like to scroll the range to the middle of the UITextView. If the range is below the visible region of the UITextView then -scrollRangeToVisible: will scroll it to the bottom. I tried getting the frame for the range myself like so:
UITextPosition *beginning = textView.beginningOfDocument;
UITextPosition *start = [textView positionFromPosition:beginning offset:range.location];
UITextPosition *end = [textView positionFromPosition:start offset:range.length];
UITextRange *textRange = [textView textRangeFromPosition:start toPosition:end];
CGRect rect = [textView firstRectForRange:textRange];
CGRect finalRect = [textView convertRect:rect fromView:textView.textInputView];
textView.contentOffset = CGPointMake(0.0,finalRect.origin.y-visibleOffetY);
And that works... sometimes. Every once and awhile the computed rect from the range will be CGRectNull (range is valid but I get CGRectNull anyway).