如何获得CTFrame上绘制的文本的真实高度

jav*_*smo 5 cocoa-touch objective-c core-text

我有一定数量的文字填补了一些CTFrame(不止一个).要创建所有框架(每页一个),我将填充一个框架,获取未使用框架的文本CTFrameGetVisibleStringRange并重复此过程,直到处理完所有文本.

在除最后一帧之外的所有帧上,文本占据页面的相同高度.在最后一帧,我想知道文本占据的真实高度,知道我可以在哪里开始绘制更多文本.

有没有办法做到这一点?

UPDATE

根据评论的要求,这是我使用@omz建议的解决方案:

我在我的项目中使用ARC:

CTFrameRef locCTFrame = (__bridge CTFrameRef)ctFrame;

//Save CTLines
lines = (NSArray *) ((__bridge id)CTFrameGetLines(locCTFrame));

//Get line origins
CGPoint lOrigins[MAXLINESPERPAGE];
CTFrameGetLineOrigins(locCTFrame, CFRangeMake(0, 0), lOrigins);
CGFloat colHeight = self.frame.size.height;

//Save the amount of the height used by text
percentFull = ((colHeight - lOrigins[[lines count] - 1].y) / colHeight);
Run Code Online (Sandbox Code Playgroud)

abu*_*sky 8

+ (CGSize)measureFrame:(CTFrameRef)frame
{
    // 1. measure width
    CFArrayRef  lines       = CTFrameGetLines(frame);
    CFIndex     numLines    = CFArrayGetCount(lines);
    CGFloat     maxWidth    = 0;

    for(CFIndex index = 0; index < numLines; index++)
    {
        CTLineRef   line = (CTLineRef) CFArrayGetValueAtIndex(lines, index);
        CGFloat     ascent, descent, leading, width;

        width = CTLineGetTypographicBounds(line, &ascent,  &descent, &leading);

        if(width > maxWidth)
            maxWidth = width;
    }

    // 2. measure height
    CGFloat ascent, descent, leading;

    CTLineGetTypographicBounds((CTLineRef) CFArrayGetValueAtIndex(lines, 0), &ascent,  &descent, &leading);
    CGFloat firstLineHeight = ascent + descent + leading;

    CTLineGetTypographicBounds((CTLineRef) CFArrayGetValueAtIndex(lines, numLines - 1), &ascent,  &descent, &leading);
    CGFloat lastLineHeight  = ascent + descent + leading;

    CGPoint firstLineOrigin;
    CTFrameGetLineOrigins(frame, CFRangeMake(0, 1), &firstLineOrigin);

    CGPoint lastLineOrigin;
    CTFrameGetLineOrigins(frame, CFRangeMake(numLines - 1, 1), &lastLineOrigin);

    CGFloat textHeight = ABS(firstLineOrigin.y - lastLineOrigin.y) + firstLineHeight + lastLineHeight;

    return CGSizeMake(maxWidth, textHeight);
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说一般都很好,除了我有高度问题.如果我理解正确,textHeight计算实际上太大了.以一行为例 - firstLineHeight == lastLineHeight和firstLineOrigin.y == lastLineOrigin.y.然后textHeight将是行高的两倍,当你实际只想要行高时,对吗? (2认同)

omz*_*omz 3

您可以使用 获取框架中最后一行的线原点,CTFrameGetLineOrigins或者使用该CTFramesetterSuggestFrameSizeWithConstraints函数获取给定范围的矩形框架的大小。如果您使用非矩形路径来设置实际帧,后者将不起作用。