UITextView.scrollRangeToVisible() broken

Depending on the amount of text in the textView, the following can cause the textView to go completely blank or scroll to a location in the middle of the text and prevent the user from scrolling to the end of the text.

let nsRange = NSMakeRange(textView.text!.count - 1, 1)
textView.scrollRangeToVisible(nsRange)

I'm looking for a workaround to do the simplest thing in the world: scroll the damn textView to the bottom.

Replies

I forgot to mention that this is an iOS 16 issue.

I have since found another bug. If you change the text attribute of a UITextView from a long string to a short one, the view will stay scrolled way down with nothing but blank space between the new text and the end of the content view.

I'm considering removing my apps from the App Store and selling my Apple products. After ten years in the Apple ecosystem, I have experienced more hardware and software issues than I have in forty years of using other platforms.

scrollRectToVisible() and setContentOffset() are also borked. Sigh.

But wait. There's more.

Not only does Xcode not support iOS 15.7, preventing you from using un-upgraded devices for development, but you cannot install on an device without putting it into developer mode. When you turn off developer mode, you cannot run the apps that you installed via Xcode.

More absurdity: In iSO 16, UIDocumentPickerviewController on my iPhone 13 Mini has no cancel button. There is no way to dismiss the view controller when it runs fullscreen. Now, I ran it fullscreen because the picker formerly had (and maybe still has) a bug. On the iPad, if you dismissed the view controller by touching outside of the frame, documentPickerWasCancelled was not called. You could not perform cleanup operations.

Anyway, this is all academic. I have deleted my apps from the App Store, and I will let my developer account expire.

Ciao, you poor Apple peasants. I feel sorry for those of you who rely on the App Store for revenue. You have hitched your wagons to a lame horse.

Has anyone found a work around for this issue? I'm experience this issue in my app.

I have found this bug in ios 16 beta 2 and posted to forum https://developer.apple.com/forums/thread/711388 and also set the bug to apple feedback. In fact scrollrangetovisible for long text brokes the textview. For the last 5 month I have observed with live interest this behaviour.

I have changed in interface builder text layout from default to text kit 1 and now scrolltovisible works correct.

  • Thx a lot, this fixed my issue!

Add a Comment

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

Here's how I fixed this iOS16 bug in my code:

if #available(iOS 16.0, *) {
            textView = UITextView(usingTextLayoutManager: false) // Must be set to false to use Text Kit 1 to fix scroll view bug
        } else {
            textView = UITextView()
        }