CTFrame clipping first line of text

I am running into a problem while using Core Text, where the first line of the text I display in a CTFrame is cut off at the top, as seen in the screenshot below, with the character "B":

CTFrame裁剪第一行的示例

I think I'm doing something wrong while setting the leading in the CTFrame . My code is below:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    CGContextRef context = UIGraphicsGetCurrentContext();

    NSAttributedString *myString;

    //Create the rectangle into which we'll draw the text
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, self.bounds);

    //Flip the coordinate system
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    //Setup leading (line height)
    CGFloat lineHeight = 25;
    CTParagraphStyleSetting settings[] = {
        { kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(CGFloat), &lineHeight },
        { kCTParagraphStyleSpecifierMaximumLineHeight, sizeof(CGFloat), &lineHeight },
    };

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
    NSDictionary * attrs = [[NSDictionary alloc] initWithObjectsAndKeys:

                                (__bridge id)CTFontCreateWithName((__bridge CFStringRef) font.fontName, font.pointSize, NULL) ,
                                (NSString*)kCTFontAttributeName,

                                (id)textColor.CGColor,
                                (NSString*)kCTForegroundColorAttributeName,

                                (__bridge id) paragraphStyle,
                                kCTParagraphStyleAttributeName,
                                nil];

    myString = [[NSAttributedString alloc] initWithString:text attributes:attrs];
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)myString);
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,[myString length]), path, NULL);

    CTFrameDraw(frame, context);
    CFRelease(frame);
    CFRelease(framesetter);
    CFRelease(path);
}

Other SO posts (this one and this one) are not really helpful.

How can I prevent the CTFrame from clipping the first line?

--EDIT--

Reducing lineheight to 20:

lineheight from the second line onwards is respected, but the baseline of the first line of text is less than 20 below the top.

在这里输入图像描述


Here CGFloat lineHeight = 25; I am sure (from your screen shot) its less than font size you are currently using ( font.pointSize ). This is the only reason of clipping top of text, as text size not able to fit in 25 points of height.

You have two options:

1) Remove paragraphStyle and its related code. Replace your NSDictionary * attrs = … by following code.

NSDictionary * attrs = [[NSDictionary alloc] initWithObjectsAndKeys:
                               (__bridge id)CTFontCreateWithName((__bridge CFStringRef) font.fontName, font.pointSize, NULL) ,
                                (NSString*)kCTFontAttributeName,
                                (id)textColor.CGColor, (NSString*)kCTForegroundColorAttributeName,
                                nil];

CTFrameDraw() will take care for line height automatically.

2) Or always provide lineHeight greater than your max font size. Like lineHeight = font.pointSize + somemargine ;

To understand above explanation try this: In your current code set your lineHeight = 20; ; you can see more text will be clipped from top line and second line text will be more closed to bottom of its top line.


I managed to fix the problem. In the end it turned out to be the location at which I flipped the coordinate system, and by flipping it earlier on in the code the problem fixed itself.

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

上一篇: 使用核心文本放置单个字形

下一篇: CTFrame剪裁文本的第一行