Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scroll to current cursor position in UITextView?

Tags:

ios

swift2

I've searched all over S.O. for a simple solution to get the cursor's current position, then scroll to it (assuming the keyboard is visible). Most seem overly complicated and/or ineffective in certain situations. How can I make scrolling work every time, whether the cursor is below a keyboard or not?

like image 684
kbpontius Avatar asked Aug 06 '15 19:08

kbpontius


1 Answers

1) Be sure your UITextView's contentInsets are properly set & your textView is already firstResponder before doing this. The contentInset property tells the textView where the visible area is for the user. If the keyboard is visible, be sure the textView.contentInset.bottom property has been set to the top border of the keyboard otherwise the textView may scroll to a space not visible, behind the keyboard.

See this S.O. post for more information: What's the UIScrollView contentInset property for?

2) After my the insets are ready to go, and the textView is firstResponder, I call the following function:

private func scrollToCursorPositionIfBelowKeyboard() {
    let caret = textView.caretRectForPosition(textView.selectedTextRange!.start)
    let keyboardTopBorder = textView.bounds.size.height - keyboardHeight!

   // Remember, the y-scale starts in the upper-left hand corner at "0", then gets
   // larger as you go down the screen from top-to-bottom. Therefore, the caret.origin.y
   // being larger than keyboardTopBorder indicates that the caret sits below the
   // keyboardTopBorder, and the textView needs to scroll to the position.
   if caret.origin.y > keyboardTopBorder {
        textView.scrollRectToVisible(caret, animated: true)
    }
 }

Optional: If you just want to scroll to the cursor's current position (assuming the textView is currently firstResponder and contentInset has been properly set before now), just call:

private func scrollToCursorPosition() {
    let caret = textView.caretRectForPosition(textView.selectedTextRange!.start)
    textView.scrollRectToVisible(caret, animated: true)
 }

Extra Information: In order to set the textView scroll bars to the proper height, modify the scrollIndicatorInsets by doing something like:

// This is not relative to the coordinate plane. You simply set the `.bottom` property 
// as if it were a normal height property. The textView does the rest for you.
textView.contentInset.bottom = keyboardHeight 
textView.scrollIndicatorInsets = textView.contentInset // Matches textView's visible space.
like image 119
kbpontius Avatar answered Nov 04 '22 17:11

kbpontius