如何将长NSString拆分成页面 [英] How to split long NSString into pages

查看:115
本文介绍了如何将长NSString拆分成页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很长的NSString我希望在几页上显示。

I have a long NSString I want to display over a couple of pages.

但要做到这一点,我需要找出实际上适合的文本数量页面。

But to do this, I need to find out how much text will actually fit on the page.

[NSString sizeWithFont:...]还不够,它只会告诉我文本是否适合矩形,如果没有,它会默默地截断字符串,但它不会告诉我它被截断的位置!

[NSString sizeWithFont: ...] Is not enough, it will just tell me if the text fits in the rectangle or not, if its does not, it will silently truncate the string, but it won't tell me where it truncated!

我需要知道第一个不适合页面的单词,所以我可以拆分字符串并在下一页上绘制它的那一部分。 (并重复)

I need to know the first word that does not fit on the page, so I can split the string and draw that part of it on the next page. (and repeat)

有任何想法如何解决这个问题?

Any ideas how to solve this?

我只知道我到目前为止是反复调用sizeWithFont:constrainedToSize:在我猜测分页符的字符串中的点附近,并分析得到的rect,但感觉很麻烦和缓慢,我觉得我可能有额外的问题让它100%准确.. (因为下降,等等。)

Only idea I have myself so far is to repeatedly call sizeWithFont:constrainedToSize: around the point in the string where I'm guessing the page break will be, and analyse the resulting rect, but it feels cumbersome and slow and I feel I might have additional problems getting it 100% accurate... (because of descenders, and whatnot.)

ofc,它必须在公共iOS SDK中可用

ofc, it has to be available in the public iOS SDK

答案:

Phew,这是一些毛茸茸的文档。这是我完成的功能作为一个例子,也许它会帮助某人,因为那里没有太多特定于iphone的核心文本示例。

Phew, that was some hairy documentation. Here is my finished function as an example, maybe it will help someone, since there isn't much iphone-specific core text examples out there.

+ (NSArray*) findPageSplits:(NSString*)string size:(CGSize)size font:(UIFont*)font;
{
  NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:32];
  CTFontRef fnt = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize,NULL);
  CFAttributedStringRef str = CFAttributedStringCreate(kCFAllocatorDefault, 
                                                       (CFStringRef)string, 
                                                       (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:(id)fnt,kCTFontAttributeName,nil]);
  CTFramesetterRef fs = CTFramesetterCreateWithAttributedString(str);
  CFRange r = {0,0};
  CFRange res = {0,0};
  NSInteger str_len = [string length];
  do {
    CTFramesetterSuggestFrameSizeWithConstraints(fs,r, NULL, size, &res);
    r.location += res.length;
    [result addObject:[NSNumber numberWithInt:res.length]];
  } while(r.location < str_len);
//  NSLog(@"%@",result);
  CFRelease(fs);
  CFRelease(str);
  CFRelease(fnt);
  return result;
}  

重要提示:

您不能将返回的范围或大小与任何UIKit类或字符串绘制函数一起使用!您只能将它与Core Text一起使用,例如创建CTFrame并绘制它。
像字距调整这样的细微差别使得无法将Core Text函数与UIKit结合起来。

You can not use the returned range or size with any UIKit classes or string drawing functions! You must only use it with Core Text, for example creating a CTFrame and drawing that. Subtle differences in things like kerning makes it impossible to combine Core Text functions with UIKit.

另外,请注意已发现返回的大小有问题。

Also, note that the returned size has been found to be buggy.

推荐答案

您应该查看自iOS 3.2以来可用的CoreText。文档相当复杂,可以在这里找到。基本上,您创建一个CTFramesetter并调用CTFramesetterSuggestFrameSizeWithConstraints。然后,您将找到适合给定CGSize的文本范围。

You should look into CoreText, available since iOS 3.2. The docs are rather complicated and can be found here. Basically you create a CTFramesetter and call CTFramesetterSuggestFrameSizeWithConstraints. You will then find the range of text that fits within a given CGSize.

这篇关于如何将长NSString拆分成页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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