如何找到可滚动,不可编辑的UITextView中可见的文本?
例如我可能需要显示下一段,然后我想查找当前可见文本范围并使用它来计算适当的范围并使用scrollRangeToVisible:
滚动文本视图
答案 0 :(得分:7)
我在这里找到另一个解决方案。 这是解决我眼中这个问题的更好方法。 https://stackoverflow.com/a/9283311/889892
由于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]);
}
这假设从上到下,从左到右的文本布局。如果您想使其适用于其他布局方向,则必须更加努力。 :)
答案 1 :(得分:4)
我这样做的方法是计算每个段落的所有大小。使用sizeWithFont:constrainedToSize:lineBreakMode:
然后,您将能够从[textView contentOffset]中找出可见的段落。
滚动,不要使用scrollRangeToVisible,只需使用setContentOffset:CGPoint y参数应该是下一段所有高度大小的总和,或者只是添加textView.frame.size.height,如果是比下一段的开头更接近。
这有道理吗?
回答评论请求代码(未经测试):
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];
答案 2 :(得分:3)
如果你想要一个Swift解决方案我会用它:
Swift 2
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
}
}
Swift 3
public extension UITextView {
public var visibleRange: NSRange? {
guard let start = closestPosition(to: contentOffset),
end = characterRange(at: CGPoint(x: contentOffset.x + bounds.maxX,
y: contentOffset.y + bounds.maxY))?.end
else { return nil }
return NSMakeRange(offset(from: beginningOfDocument, to: start), offset(from: start, to: end))
}
}
答案 3 :(得分:1)
您拥有的一个选项是使用UIWebView而不是UITextView。然后,您可以使用锚点和JavaScript来滚动到文本中的适当位置。您可以在每个段落的开头以编程方式插入锚点,以使其更容易。
答案 4 :(得分:1)
基于"Noodle of Death" answer的Swift 3.0 / 3.1解决方案。
@Stateful
@LocalBean
public class UserBean
{
private String name;
public String getName() { return name; }
public void setName( String name_ ) { name = name_; }
}