Ios 如何在UITextView中高效地查找可见单词的CGRECT?
我的目标是在UITextView中标记所有可见的拼写错误的单词 效率低下的算法是使用拼写检查器查找文本中所有拼写错误的单词,使用positionFromPosition:inDirection:offset等将它们转换为UITextRange对象,然后使用UITExtOutput方法firstRectFromRange获取图形矩形 因此,所有文本->拼写错误的单词->NSRange集合->uitextange集合->CGRect集合->评估可见性,绘制可见的 问题是,这需要检查所有文本,并将所有拼写错误的单词转换为图形矩形 因此,我想我们的方法是找出UITextView中当前可见的底层.text的哪些部分 因此,对于可见文本范围->拼写错误的单词->NSRange集合->uitextange集合->CGRect集合->评估可见性,绘制可见文本 中的代码可以作为一种绑定要检查的文本部分的方法,但仍然需要测量所有文本,我想这可能会非常昂贵Ios 如何在UITextView中高效地查找可见单词的CGRECT?,ios,Ios,我的目标是在UITextView中标记所有可见的拼写错误的单词 效率低下的算法是使用拼写检查器查找文本中所有拼写错误的单词,使用positionFromPosition:inDirection:offset等将它们转换为UITextRange对象,然后使用UITExtOutput方法firstRectFromRange获取图形矩形 因此,所有文本->拼写错误的单词->NSRange集合->uitextange集合->CGRect集合->评估可见性,绘制可见的 问题是,这需要检查所有文本,并将所有
有什么建议吗?因为
UITextView
是UIScrollView
的一个子类,所以它的bounds
属性反映了其坐标系的可见部分。因此,类似这样的方法应该有效:
- (NSRange)visibleRangeOfTextView:(UITextView *)textView {
CGRect bounds = textView.bounds;
UITextPosition *start = [textView characterRangeAtPoint:bounds.origin].start;
UITextPosition *end = [textView characterRangeAtPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))].end;
return NSMakeRange([textView offsetFromPosition:textView.beginningOfDocument toPosition:start],
[textView offsetFromPosition:start toPosition:end]);
}
这假定为从上到下、从左到右的文本布局。如果您想使其适用于其他布局方向,则必须更加努力。:) 罗布的回答,用Swift 4写成。我增加了一些安全检查
private func visibleRangeOfTextView(textView: UITextView) -> NSRange {
let bounds = textView.bounds
let origin = CGPoint(x: 10, y: 10)
guard let startCharacterRange = textView.characterRange(at: origin) else {
return NSRange(location: 0, length: 0)
}
let startPosition = startCharacterRange.start
let endPoint = CGPoint(x: bounds.maxX,
y: bounds.maxY)
guard let endCharacterRange = textView.characterRange(at: endPoint) else {
return NSRange(location: 0, length: 0)
}
let endPosition = endCharacterRange.end
let startIndex = textView.offset(from: textView.beginningOfDocument, to: startPosition)
let endIndex = textView.offset(from: startPosition, to: endPosition)
return NSRange(location: startIndex, length: endIndex)
}
使用示例,通过点击按钮调用:
@IBAction func buttonTapped(sender: AnyObject) {
let range = visibleRangeOfTextView(self.textView)
// Note: "as NSString" won't work correctly with Emoji and stuff,
// see also: http://stackoverflow.com/a/24045156/1085556
let nsText = self.textView.text as NSString
let text = nsText.substringWithRange(range)
NSLog("range: \(range), text = \(text)")
}
美好的为了提高效率,通过从开始向前移动长度字符来查找结尾-结果表明,在文档中从开始到结束的过程很慢,但前进成本很低。当你说“这样应该行得通”时,你真的尝试过吗?对我来说,这几乎是实际视觉文本范围的三倍。谢谢。@JasonTyler对我很有用。可能需要Xcode 6。