问题描述
我正在尝试将滚动文本的位置保存在 UITextView
中,以便在再次加载 ViewController
时可以返回到该位置.我有很长的字符串,所以我希望用户能够滚动到特定位置,然后稍后返回到该位置.
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.
我正在使用 UITextView
.scrollRangeToVisible 函数自动滚动文本视图,但我不知道如何获取用户看到的文本的 NSRange.这是最好的方法吗?我尝试使用 setContentOffset
函数,但似乎没有任何作用.
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.
感谢任何帮助.谢谢!
推荐答案
我还没有对此进行彻底的测试,但我相信以下内容应该有效.您需要的 API 记录在 UITextInput
协议中,UITextView
采用哪个.
I haven't tested this thoroughly but I believe the following should work. The APIs you need are documented in the UITextInput
protocol, which UITextView
adopts.
您首先需要获取对应于视图内给定点的 UITextPosition
.然后将该值转换为 UTF-16 字符偏移量.例如,这里我在每次滚动视图时打印 textView
的可见文本范围(以 UTF-16 代码单位表示):
You first need to get the UITextPosition
that corresponds to a given point inside the view. You'd then convert this value into a UTF-16 character offset. For example, here I print the visible text range (in terms of UTF-16 code units) of a textView
every time the view is scrolled:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let topLeft = CGPoint(x: textView.bounds.minX, y: textView.bounds.minY)
let bottomRight = CGPoint(x: textView.bounds.maxX, y: textView.bounds.maxY)
guard let topLeftTextPosition = textView.closestPosition(to: topLeft),
let bottomRightTextPosition = textView.closestPosition(to: bottomRight)
else {
return
}
let charOffset = textView.offset(from: textView.beginningOfDocument, to: topLeftTextPosition)
let length = textView.offset(from: topLeftTextPosition, to: bottomRightTextPosition)
let visibleRange = NSRange(location: charOffset, length: length)
print("Visible range: \(visibleRange)")
}
在我的测试中,UITextView
倾向于计算几乎不包含在可见范围内(例如仅一个像素)的行,因此报告的可见范围往往比可见范围大一两行人类用户会说.您可能需要对传递给 closesPosition(to:)
的确切 CGPoint
进行试验,以获得所需的结果.
In my tests, UITextView
tended to count lines that were barely included in the visible range (e.g. by only one pixel), so the reported visible range tended to be one or two lines larger than what a human user would say. You may have to experiment with the exact CGPoint
you pass into closesPosition(to:)
to get the results you want.
这篇关于在 UITextView 中滚动后获取可见文本的 NSRange的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!