iOS-如何在UITEXTVIEW中找到可见的文本范围是什么?

发布于 2024-11-08 03:21:05 字数 8 浏览 0 评论 0原文

continue

how to find what text is visible in a scrollable, non-ediable UITextView?

for example i may need to show next paragraph, then i want to find the current visible text range and use it to calculate the appropriate range and use scrollRangeToVisible: to scroll the text view

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

2024-11-15 03:21:05

I find another solution here.
It's a better way to solve this problem in my eyes.
https://stackoverflow.com/a/9283311/889892

Since UITextView is a subclass of UIScrollView, its bounds property reflects the visible part of its coordinate system. So something like this should work:

-(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]);
}

This assumes a top-to-bottom, left-to-right text layout. If you want to make it work for other layout directions, you will have to work harder. :)

I find another solution here.
It's a better way to solve this problem in my eyes.
https://stackoverflow.com/a/9283311/889892

Since UITextView is a subclass of UIScrollView, its bounds property reflects the visible part of its coordinate system. So something like this should work:

-(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]);
}

This assumes a top-to-bottom, left-to-right text layout. If you want to make it work for other layout directions, you will have to work harder. :)

み零 2024-11-15 03:21:05

continue

The way i would do it is to compute all the sizes of each paragraph. With sizeWithFont:constrainedToSize:lineBreakMode:

you will then be able to work out which paragraph is visible, from the [textView contentOffset].

to scroll, dont use scrollRangeToVisible, just use setContentOffset: The CGPoint y parameter for this should either be the sum of all the height sizes to the next paragraph, or just add the textView.frame.size.height, if that is closer than the beginning of the next paragraph.

This make sense?

in answer to comment requst code bellow (untested):

  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];
じее 2024-11-15 03:21:05

如果你想要一个 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))
    }
}

If you want a Swift solution I use this:

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))
    }
}
抱着落日 2024-11-15 03:21:05

基于Noodle of Death”答案的 Swift 3.0/3.1 解决方案。

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
    }
}

Swift 3.0/3.1 solution based on "Noodle of Death" answer.

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
    }
}
各自安好 2024-11-15 03:21:05

您的一种选择是使用 UIWebView 而不是 UITextView。然后,您可以使用锚点和 javascript 滚动到文本中的适当位置。您可以以编程方式在每个段落的开头插入锚点,以使这更容易。

One option you have is to use a UIWebView instead of a UITextView. You can then use anchors and javascript to scroll to the appropriate places in the text. You can probably insert the anchors programmatically at the start of each paragraph to make this easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文