Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在UITextView中高效地查找可见单词的CGRECT?_Ios - Fatal编程技术网

Ios 如何在UITextView中高效地查找可见单词的CGRECT?

Ios 如何在UITextView中高效地查找可见单词的CGRECT?,ios,Ios,我的目标是在UITextView中标记所有可见的拼写错误的单词 效率低下的算法是使用拼写检查器查找文本中所有拼写错误的单词,使用positionFromPosition:inDirection:offset等将它们转换为UITextRange对象,然后使用UITExtOutput方法firstRectFromRange获取图形矩形 因此,所有文本->拼写错误的单词->NSRange集合->uitextange集合->CGRect集合->评估可见性,绘制可见的 问题是,这需要检查所有文本,并将所有

我的目标是在UITextView中标记所有可见的拼写错误的单词

效率低下的算法是使用拼写检查器查找文本中所有拼写错误的单词,使用positionFromPosition:inDirection:offset等将它们转换为UITextRange对象,然后使用UITExtOutput方法firstRectFromRange获取图形矩形

因此,所有文本->拼写错误的单词->NSRange集合->uitextange集合->CGRect集合->评估可见性,绘制可见的

问题是,这需要检查所有文本,并将所有拼写错误的单词转换为图形矩形

因此,我想我们的方法是找出UITextView中当前可见的底层.text的哪些部分

因此,对于可见文本范围->拼写错误的单词->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。