CTFramesetterSuggestFrameSizeWithConstraints有时返回不正确的大小?

car*_*loe 12 iphone xcode core-graphics core-text

在下面的代码中,CTFramesetterSuggestFrameSizeWithConstraints有时返回一个CGSize高度不足以包含传递给它的所有文本的高度.我确实看过这个答案.但在我的情况下,文本框的宽度需要是恒定的.有没有其他/更好的方法来确定我的属性字符串的正确高度?谢谢!

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedString);
CGSize tmpSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0,0), NULL, CGSizeMake(self.view.bounds.size.width, CGFLOAT_MAX), NULL); 
CGSize textBoxSize = CGSizeMake((int)tmpSize.width + 1, (int)tmpSize.height + 1);
Run Code Online (Sandbox Code Playgroud)

小智 56

CTFramesetterSuggestFrameSizeWithConstraints正常工作.您获得高度太短的原因是因为附加到属性字符串的默认段落样式中的前导.如果未将段落样式附加到字符串,则CoreText将返回呈现文本所需的高度,但行之间没有空格.这让我永远想通了.文档中没有任何内容可以解释它.我碰巧注意到我的高度很短,等于(行数x预期领先).要获得高度结果,您可以使用如下代码:

NSString  *text = @"This\nis\nsome\nmulti-line\nsample\ntext."
UIFont    *uiFont = [UIFont fontWithName:@"Helvetica" size:17.0];
CTFontRef ctFont = CTFontCreateWithName((CFStringRef) uiFont.fontName, uiFont.pointSize, NULL);

//  When you create an attributed string the default paragraph style has a leading 
//  of 0.0. Create a paragraph style that will set the line adjustment equal to
//  the leading value of the font.
CGFloat leading = uiFont.lineHeight - uiFont.ascender + uiFont.descender;
CTParagraphStyleSetting paragraphSettings[1] = { kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof (CGFloat), &leading };

CTParagraphStyleRef  paragraphStyle = CTParagraphStyleCreate(paragraphSettings, 1);
CFRange textRange = CFRangeMake(0, text.length);

//  Create an empty mutable string big enough to hold our test
CFMutableAttributedStringRef string = CFAttributedStringCreateMutable(kCFAllocatorDefault, text.length);

//  Inject our text into it
CFAttributedStringReplaceString(string, CFRangeMake(0, 0), (CFStringRef) text);

//  Apply our font and line spacing attributes over the span
CFAttributedStringSetAttribute(string, textRange, kCTFontAttributeName, ctFont);
CFAttributedStringSetAttribute(string, textRange, kCTParagraphStyleAttributeName, paragraphStyle);

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(string);
CFRange fitRange;

CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, textRange, NULL, bounds, &fitRange);

CFRelease(framesetter);
CFRelease(string);
Run Code Online (Sandbox Code Playgroud)

  • 即使使用Chris的代码,它仍然对我来说太短了. (4认同)
  • 不!!仍然不适合我:( (3认同)
  • 那么当你在属性字符串中有多个字体时,怎么做呢? (2认同)

Lil*_*ard 20

CTFramesetterSuggestFrameSizeWithConstraints()被打破.我一会儿就提出了一个错误.您可以选择使用CTFramesetterCreateFrame()足够高的路径.然后你可以测量你得到的CTFrame的矩形.请注意,您不能使用CGFLOAT_MAX高度,因为CoreText使用iPhone的翻转坐标系统,并将其文本定位在框的"顶部".这意味着如果你使用CGFLOAT_MAX,你将没有足够的精度来实际告诉盒子的高度.我建议使用像10,000这样的高度,因为它比屏幕本身高10倍,并且为得到的矩形提供了足够的精度.如果你需要布置更高版本的文本,你可以为文本的每个部分多次执行此操作(您可以向CTFrameRef询问其能够布局的原始字符串中的范围).