15

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

CTFrameGetVisibleStringRange(rect).length

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

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

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

谢谢,
道格

4

1 回答 1

22

您需要的是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);

由于 ARC 仅发布 Objective-C 对象,而 CoreText 处理 C,因此您很可能会在此处发生内存泄漏。如果您NSAttributedString很小并且您只做一次,那么您不应该产生任何不良后果。但是如果你有一个循环来计算,比如说,50 个高度的 big/complex NSAttributedString,而你不释放CTFramesetterRef,你可能会出现严重的内存泄漏。查看链接的教程以获取有关内存泄漏和使用仪器进行调试的更多信息。

所以这个问题的解决方案是添加CFRelease(frameSetter);

于 2011-08-10T16:27:03.657 回答