CATextLayer + NSAttributtedString + CTParagraphStyleRef

我想有一些自定义的行间距的文本,所以我写了一个CTParagraphStyleAttributte的属性string,并将其传递给我的CATextLayer

 UIFont *font = [UIFont systemFontOfSize:20]; CTFontRef ctFont = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize, NULL); CGColorRef cgColor = [UIColor whiteColor].CGColor; CGFloat leading = 25.0; CTTextAlignment alignment = kCTRightTextAlignment; // just for test purposes const CTParagraphStyleSetting styleSettings[] = { {kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof(CGFloat), &leading}, {kCTParagraphStyleSpecifierAlignment, sizeof(CTTextAlignment), &alignment} }; CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(styleSettings, 2)); NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: (id)ctFont, (id)kCTFontAttributeName, (id)cgColor, (id)kCTForegroundColorAttributeName, (id)paragraphStyle, (id)kCTParagraphStyleAttributeName, nil]; CFRelease(ctFont); CFRelease(paragraphStyle); NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes]; _textLayer.string = attrStr; [attrStr release]; 

但行高不变。 我想我在这里失去了一些东西,但我不知道是什么。

我已经尝试过使用kCTParagraphStyleSpecifierLineSpacingAdjustmentkCTParagraphStyleSpecifierLineSpacing但其中任何一个似乎都不起作用(?)。 我也尝试使用kCTParagraphStyleSpecifierAlignment设置alignment(我知道CATextLayer有一个属性)只是为了testingkCTParagraphStyleAttributeName确实工作,它没有。

我注意到,即使我传递了一些疯狂的值(例如: CTParagraphStyleCreate(styleSettings, -555); ),这让我自问: CATextLayer是否支持段落属性? 如果是这样,我在这里错过了什么?

我试过你的代码,把NSAttributedString放在一个CATextLayer中,它忽略了格式化,就像你说的那样。

然后我尝试使用CTFrameDraw绘制完全相同的属性string到一个UIView drawRect方法,它服从所有您的格式。 我只能假设CATextLayer忽略了大部分的格式。 CATextLayer类参考有许多关于它在效率利益方面的警告。

如果你真的需要画一个CALayer ,而不是一个UIView ,你可以创build你自己的CALayer子类或委托,然后在那里画图。

 - (void)drawRect:(CGRect)rect { // // Build attrStr as before. // CGContextRef ctx = UIGraphicsGetCurrentContext(); CGRect bounds = [self bounds]; // Text ends up drawn inverted, so we have to reverse it. CGContextSetTextMatrix(ctx, CGAffineTransformIdentity); CGContextTranslateCTM( ctx, bounds.origin.x, bounds.origin.y+bounds.size.height ); CGContextScaleCTM( ctx, 1, -1 ); // Build a rectangle for drawing in. CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, bounds); // Create the frame and draw it into the graphics context CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrStr); CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); CFRelease(framesetter); CFRelease(path); // Finally do the drawing. CTFrameDraw(frame, ctx); CFRelease(frame); }