核心文本的CTFramesetterSuggestFrameSizeWithConstraints()每次都会返回不正确的大小

根据文档, CTFramesetterSuggestFrameSizeWithConstraints () “确定字符串范围所需的帧大小”。

不幸的是,这个函数返回的大小从来都不准确。 这是我正在做的事情:

    NSAttributedString *string = [[[NSAttributedString alloc] initWithString:@"lorem ipsum" attributes:nil] autorelease];
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef) string);
    CGSize textSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0,0), NULL, CGSizeMake(rect.size.width, CGFLOAT_MAX), NULL);

返回的尺寸始终具有计算的正确宽度,但高度始终略低于预期值。

这是使用这种方法的正确方法吗?

有没有其他的方式来布局核心文本?

似乎我不是唯一遇到这种方法的问题。 请参阅https://devforums.apple.com/message/181450。

编辑:我使用sizeWithFont:测量了与Quartz相同的字符串sizeWithFont: ,为属性字符串和Quartz提供相同的字体。 以下是我收到的测量结果:

核心文本:133.569336 x 16.592285

石英:135.000000 x 31.000000


试试这个..似乎工作:

+(CGFloat)heightForAttributedString:(NSAttributedString *)attrString forWidth:(CGFloat)inWidth
{
    CGFloat H = 0;

    // Create the framesetter with the attributed string.
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString( (CFMutableAttributedStringRef) attrString); 

    CGRect box = CGRectMake(0,0, inWidth, CGFLOAT_MAX);

    CFIndex startIndex = 0;

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, box);

    // Create a frame for this column and draw it.
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(startIndex, 0), path, NULL);

    // Start the next frame at the first character not visible in this frame.
    //CFRange frameRange = CTFrameGetVisibleStringRange(frame);
    //startIndex += frameRange.length;

    CFArrayRef lineArray = CTFrameGetLines(frame);
    CFIndex j = 0, lineCount = CFArrayGetCount(lineArray);
    CGFloat h, ascent, descent, leading;

    for (j=0; j < lineCount; j++)
    {
        CTLineRef currentLine = (CTLineRef)CFArrayGetValueAtIndex(lineArray, j);
        CTLineGetTypographicBounds(currentLine, &ascent, &descent, &leading);
        h = ascent + descent + leading;
        NSLog(@"%f", h);
        H+=h;
    }

    CFRelease(frame);
    CFRelease(path);
    CFRelease(framesetter);


    return H;
}

对于单线框架,请尝试以下操作:

line = CTLineCreateWithAttributedString((CFAttributedStringRef) string);
CGFloat ascent;
CGFloat descent;
CGFloat width = CTLineGetTypographicBounds(line, &ascent, &descent, NULL);
CGFloat height = ascent+descent;
CGSize textSize = CGSizeMake(width,height);

对于多行框架,还需要添加行的引导(请参阅Core Text Programming Guide中的示例代码)

出于某种原因, CTFramesetterSuggestFrameSizeWithConstraints()正在使用上升和下降的差异来计算高度:

CGFloat wrongHeight = ascent-descent;
CGSize textSize = CGSizeMake(width, wrongHeight);

这可能是一个错误?

我在框架的宽度上遇到了一些其他问题; 这是值得检查的,因为它只在特殊情况下显示。 看到这个问题更多。


问题在于,在测量之前,您必须对文本应用段落样式。 如果你不这样做,你会得到默认的0.0。 我在https://stackoverflow.com/a/10019378/1313863上提供了一个代码示例,用于解答此问题的重复问题。

链接地址: http://www.djcxy.com/p/81899.html

上一篇: Core Text's CTFramesetterSuggestFrameSizeWithConstraints() returns incorrect size every time

下一篇: How do I convert NSMutableArray to NSArray?