CoreText。如何计算属性字符串的边界框?

时间:2011-08-08 20:58:33

标签: core-text nsattributedstring

在CoreText中,很容易问:“对于给定的矩形,这个属性字符串有多少适合?”。

CTFrameGetVisibleStringRange(rect).length

将返回字符串中的下一行文本应该开始的位置。

我的问题是:“给定一个属性字符串和宽度,我需要什么矩形高度来完全绑定属性字符串?”。

CoreText框架是否提供了执行此操作的工具?

谢谢,
道格

1 个答案:

答案 0 :(得分:23)

您需要的是CTFramesetterSuggestFrameSizeWithConstraints(),您可以这样使用它:

CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedString)); /*Create your framesetter based in you NSAttrinbutedString*/
CGFloat widthConstraint = 500; // Your width constraint, using 500 as an example
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(
   framesetter, /* Framesetter */
   CFRangeMake(0, text.length), /* String range (entire string) */
   NULL, /* Frame attributes */
   CGSizeMake(widthConstraint, CGFLOAT_MAX), /* Constraints (CGFLOAT_MAX indicates unconstrained) */
   NULL /* Gives the range of string that fits into the constraints, doesn't matter in your situation */
);
CGFloat suggestedHeight = suggestedSize.height;

修改

//IMPORTANT: Release the framesetter, even with ARC enabled!
CFRelease(frameSetter);

As ARC releases only Objective-C objects,CoreText处理C,很可能你会在这里发生内存泄漏。如果你的NSAttributedString很小并且你做了一次,那么你不应该有任何不良后果。但是,如果你有一个循环来计算,比方说,大/复杂NSAttributedString的50个高度,并且你没有释放CTFramesetterRef,你可能会有严重的内存泄漏。查看链接的教程,了解有关内存泄漏和使用仪器调试的更多信息。

因此,此问题的解决方案是添加CFRelease(frameSetter);