How can I scroll to the current cursor position in a UITextView?
I have searched all SO for a simple solution to get the current cursor position, then scroll to it (assuming the keyboard visible). Most of them seem overly complicated and / or ineffective in certain situations. How can I scroll every time whether the cursor is below the keyboard or not?
source to share
1) Make sure yours is UITextView
contentInset
installed correctly and yours is textView
already installed firstResponder
. The property contentInset
tells textView
where the visible area is for the user. If the keyboard is visible, make sure the property is textView.contentInset.bottom
set to the top border of the keyboard, otherwise it textView
may scroll to a place that is not visible behind the keyboard.
See this SO post for more information: What is the UIScrollView contentInset property for?
2) After my inserts are ready to go , and textView
- 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 jump to the current cursor position (if it textView
is currently currently firstResponder
and has contentInset
been set correctly up to that point), just call:
private func scrollToCursorPosition() {
let caret = textView.caretRectForPosition(textView.selectedTextRange!.start)
textView.scrollRectToVisible(caret, animated: true)
}
Additional info: To set the scrollbars textView
to the desired height, modify 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 visible space.
source to share