I'm trying to save the location of scrolled text in a UITextView so that I can return to that location upon loading the ViewController again. I have very long strings, so I want the user to be able to scroll to a specific location and then return to that location later.
I'm using the UITextView. scrollRangeToVisible function to automatically scroll the text view, but I don't know how to get the NSRange of the text that the user is seeing. Is this the best way to go about this? I tried using the setContentOffset function but that didn't seem to do anything.
Any help is appreciated. Thanks!
Here's a little extension on UITextView that uses its characterRange(at:) function instead. It also adds a computed property to return the currently visible text:
extension UITextView {
private var firstVisibleCharacterPosition: UITextPosition? {
// ⚠️ For some reason `characterRange(at:)` returns nil for points with a low y value.
guard let scrolledPosition = characterRange(at: contentOffset)?.start else {
return beginningOfDocument
}
return scrolledPosition
}
private var lastVisibleCharacterPosition: UITextPosition? {
return characterRange(at: bounds.max)?.end
}
/// The range of the text that is currently displayed within the text view's bounds.
var visibleTextRange: UITextRange? {
guard
let first = firstVisibleCharacterPosition,
let last = lastVisibleCharacterPosition else {
return nil
}
return textRange(from: first, to: last)
}
/// The string that is currently displayed within the text view's bounds.
var visibleText: String? {
guard let visibleTextRange = visibleTextRange else {
return nil
}
return text(in: visibleTextRange)
}
}
I used these shorthand properties in the code above:
extension CGRect {
var min: CGPoint {
return .init(x: minX, y: minY)
}
var max: CGPoint {
return .init(x: maxX, y: maxY)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With