ios – 如何findUITextView中的文本的可见范围?

如何find在可滚动的,不可编辑的UITextView中可见的文本?

例如我可能需要显示下一个段落,那么我想find当前可见的文本范围,并使用它来计算适当的范围,并使用scrollRangeToVisible:滚动文本视图

我会这样做的方式是计算每个段落的所有大小。 用sizeWithFont:constrainedToSize:lineBreakMode:

那么您将能够从[textView contentOffset]中找出哪一段可见。

滚动,不使用scrollRangeToVisible,只是使用setContentOffset:这个CGPoint y参数应该是所有的高度尺寸的总和下一个段落,或者只是添加textView.frame.size.height,如果是比下一段的开始。

这有道理?

在回答评论请求代码下面(未经testing):

  CGFloat paragraphOffset[MAX_PARAGRAPHS]; CGSize constraint = CGSizeMake(widthOfTextView, 999999 /*arbitrarily large number*/); NSInteger paragraphNo = 0; CGFloat offset = 0; for (NSString* paragraph in paragraphs) { paragraphOffset[paragraphNo++] = offset; CGSize paragraphSize = [paragraph sizeWithFont:textView.font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; offset += paragraphSize.height; } // find visible paragraph NSInteger visibleParagraph = 0; while (paragraphOffset[visibleParagraph++] < textView.contentOffset.y); // scroll to paragraph 6 [textView setContentOffset:CGPointMake(0, paragraphOffset[6]) animated:YES]; 

我在这里find另一个解 在我眼中解决这个问题是一个更好的方法。 https://stackoverflow.com/a/9283311/889892

由于UITextView是UIScrollView的子类,其边界属性反映了其坐标系的可见部分。 所以这样的事情应该工作:

 -(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解决scheme,我使用这个:

 public extension UITextView { public var visibleRange: NSRange? { if let start = closestPositionToPoint(contentOffset) { if let end = characterRangeAtPoint(CGPointMake(contentOffset.x + CGRectGetMaxX(bounds), contentOffset.y + CGRectGetMaxY(bounds)))?.end { return NSMakeRange(offsetFromPosition(beginningOfDocument, toPosition: start), offsetFromPosition(start, toPosition: end)) } } return nil } } 

你有一个select是使用UIWebView而不是UITextView。 然后,您可以使用锚点和JavaScript滚动到文本中的相应位置。 您可能可以在每个段落的开头以编程方式插入锚点,以使这更容易。

Swift 3.0 / 3.1解决scheme基于“ 面死 ”的答案。

 public extension UITextView { public var visibleRange: NSRange? { if let start = closestPosition(to: contentOffset) { if let end = characterRange(at: CGPoint(x: contentOffset.x + bounds.maxX, y: contentOffset.y + bounds.maxY))?.end { return NSMakeRange(offset(from: beginningOfDocument, to: start), offset(from: start, to: end)) } } return nil } }