在NSAttributedString的drawWithRect中查找最后一个可见行索引 [英] Find last visible line index in NSAttributedString's drawWithRect

查看:446
本文介绍了在NSAttributedString的drawWithRect中查找最后一个可见行索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从用户提供的文本创建一个pdf,但是当文本对于页面来说太大时我有问题,我必须计算文本将被切断的位置,以便我可以将下一个块移动到下一页。我使用此代码绘制属性文本:

I am creating a pdf from user provided text, however I have an issue when the text is too big for the page, I have to calculate where the text would be cut off so I can move the next chunk to the next page. I use this code to draw the attributed text:

    CGRect rect = CGRectFromString(elementInfo[@"rect"]);
    NSString *text = elementInfo[@"text"];
    NSDictionary *attributes = elementInfo[@"attributes"];
    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:text attributes:attributes];
    [attString drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine context:nil];

如何获得最后一条可见线的位置?

How can I get the place where the "last visible line" is?

推荐答案

这个解决方案的作用是检查你的文本是否适合给定的 UITextView 框架和字体,如果没有,它会删除字符串中的最后一个单词,并再次检查它是否适合。它继续这个过程,直到它适合给定的帧。一旦它达到给定的大小,就会返回字符串应该被拆分的索引。

What this solution does is it checks if your text will fit within a UITextView with the given frame and font, and if not, it removes the last word from the string and checks again if it fits. It continues this process until it fits in the given frame. Once it gets within the given size, the index where the string should be split is returned.

- (NSUInteger)pageSplitIndexForString:(NSString *)string 
                              inFrame:(CGRect)frame 
                             withFont:(UIFont *)font
{
    CGFloat fixedWidth = frame.size.width;
    UITextView *textView = [[UITextView alloc] initWithFrame:frame];
    textView.text = string;
    textView.font = font;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);

    while (newFrame.size.height > frame.size.height) {
        textView.text = [self removeLastWord:textView.text];

        newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
        newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    }

    NSLog(@"Page one text: %@", textView.text);

    NSLog(@"Page two text: %@", [string substringFromIndex:textView.text.length]);

    return textView.text.length;
}

删除最后一个字的方法:

Method to remove last word:

- (NSString *)removeLastWord:(NSString *)str
{
    __block NSRange lastWordRange = NSMakeRange([str length], 0);
    NSStringEnumerationOptions opts = NSStringEnumerationByWords | NSStringEnumerationReverse | NSStringEnumerationSubstringNotRequired;
    [str enumerateSubstringsInRange:NSMakeRange(0, [str length]) options:opts usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        lastWordRange = substringRange;
        *stop = YES;
    }];
    return [str substringToIndex:lastWordRange.location];
}

使用此 pageSplit 方法,您可以调用它并根据提供的字符串的长度检查返回的索引。如果返回的索引小于字符串的长度,则表示您需要拆分为第二页。

To use this "pageSplit" method, you would call it and check the returned index against the length of the supplied string. If the returned index is less than the string's length, you know you'll need to split into a second page.

为了给予信用到期的一些信用,我借了来自其他几个SO答案的代码(如何根据其内容调整UITextView的大小?获取NSString的最后一个单词)以提出我的解决方案。

To give some credit where credit is due, I borrowed code from a couple other SO answers (How do I size a UITextView to its content? and Getting the last word of an NSString) to come up with my solution.

根据您的评论,我编辑了我的答案,您可以使用一种方法发送详细信息并在要分割的字符串中找回索引。您提供字符串,容器大小和字体,它将告诉您页面拆分的位置(字符串中的索引)。

Per your comments, I've edited my answer to have a method where you can send the particulars and get back the index within the string you want to split. You supply the string, container size, and font and it will let you know where the page split will occur (index within the string).

这篇关于在NSAttributedString的drawWithRect中查找最后一个可见行索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆