3

假设我正在使用 Core Text 为 iPhone 编写文本查看器。每次用户更改基本字体大小时,我都需要计算显示具有给定字体大小的整个 NSAttributedString 需要多少页(固定大小的 CGRects)。

而且我想在单独的 NSOperation 中执行此操作,以便用户不会遇到不必要的 UI 滞后。

不幸的是,要计算页数,我需要使用不可见文本绘图模式绘制我的框架 (CTFrameDraw),然后使用 CTFrameGetVisibleStringRange 来计算字符数。但是要绘制文本,我需要一个 CGContext。问题从这里开始......

我可以通过调用 UIGraphicsGetCurrentContext 在 drawRect 中获取 CGContext,但在这种情况下:

  1. 我必须使用 performSelectorOnMainThread 调用对 CGContext 进行操作的任何方法,对吗?
  2. 另一个线程应该 CFRetain 这个上下文。在drawRect方法之外使用drawRect的CGContext是否可以接受?

还有其他解决方案吗?在工作线程中创建单独的 CGContext?如何?CGBitmap上下文?我如何确定所有条件(我不知道,分辨率?等)都与 drawRect 的 CGContext 中的相同,以便正确计算页面?

4

3 回答 3

0

您可以使用 CTFramesetterSuggestFrameSizeWithConstraints。

在这里查看我的问题:如何将长 NSString 拆分为页面

于 2010-10-05T20:27:41.160 回答
0

在从 CTFrameGetVisibleStringRange 获取结果之前,您不需要 CTFrameDraw

于 2010-11-17T03:17:52.873 回答
0

使用 CTFramesetterSuggestFrameSizeWithConstraints ,如果指定 fitRange 参数,则返回字符串的实际范围

+ (NSArray*) pagesWithString:(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);

  CFRelease(fs);
  CFRelease(str);
  CFRelease(fnt);
  return result;
}  
于 2013-02-17T07:58:29.853 回答