我想要一些带有自定义行间距的文字,所以我用CTParagraphStyleAttributte
写了一个属性字符串并将其传递给我的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];
但线高不变。我想我在这里错过了一些东西,但我不知道是什么。
我尝试使用kCTParagraphStyleSpecifierLineSpacingAdjustment
和kCTParagraphStyleSpecifierLineSpacing
,但其中任何一个似乎都不起作用(?)。我还尝试使用kCTParagraphStyleSpecifierAlignment
设置对齐(我知道CATextLayer
有一个属性),只是为了测试kCTParagraphStyleAttributeName
确实有效,但事实并非如此。
我注意到即使我传递了一些疯狂的值(例如:CTParagraphStyleCreate(styleSettings, -555);
),这也让我问自己:CATextLayer
是否支持段落属性?如果是的话,我在这里错过了什么?
答案 0 :(得分:3)
我尝试了你的代码,将NSAttributedString放在CATextLayer中,它忽略了格式化,如你所说。
然后我尝试使用drawRect
将完全相同的属性字符串绘制到UIView CTFrameDraw
方法,并且它遵循所有格式。我只能假设CATextLayer忽略了它的大部分格式。 CATextLayer Class Reference有许多关于它为了效率而做了什么的警告。
如果你真的需要绘制到CALayer
而不是UIView
,你可以创建自己的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);
}