本文介绍了CATextLayer + NSAttributtedString + CTParagraphStyleRef的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一些带有自定义行距的文本,所以我用CTParagraphStyleAttributte编写了一个属性字符串,并将其传递给我的CATextLayer:

I want to have some text with a custom line-spacing, so I wrote an attribute string with CTParagraphStyleAttributte and pass it to my 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];

但是行高没有改变.我想我在这里遗漏了一些东西,但我不知道该怎么办.

But the line height is not changing. I think I am missing something here but I don't know what.

我尝试过使用kCTParagraphStyleSpecifierLineSpacingAdjustmentkCTParagraphStyleSpecifierLineSpacing,但是它们似乎都不起作用(?).我还尝试使用kCTParagraphStyleSpecifierAlignment设置对齐方式(我知道CATextLayer具有该属性),只是为了测试kCTParagraphStyleAttributeName确实有效,但是没有.

I've tried with kCTParagraphStyleSpecifierLineSpacingAdjustment and kCTParagraphStyleSpecifierLineSpacing but either of them don't seem to work (?). I tried also to set the alignment using kCTParagraphStyleSpecifierAlignment (I know CATextLayer has a property for that) just to test kCTParagraphStyleAttributeName is indeed working and it didn't.

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

I've noticed that even if I pass some crazy values (for example: CTParagraphStyleCreate(styleSettings, -555);) which leads me to ask myself: Does CATextLayer support paragraph attributes? If so, what am I missing here?

推荐答案

我尝试了您的代码,将NSAttributedString放在CATextLayer中,并且正如您所说的那样,它忽略了格式设置.

I tried your code, putting the NSAttributedString in a CATextLayer, and it ignored the formatting, as you said.

然后,我尝试使用CTFrameDraw将完全相同的属性字符串绘制到UIView drawRect方法中,它遵循所有格式.我只能假定CATextLayer忽略了其大部分格式. CATextLayer类参考具有一个有关其为提高效率所做的警告的次数.

Then I tried drawing the exact same attributed string to a UIView drawRect method using CTFrameDraw, and it obeyed all your formatting. I can only assume that CATextLayer ignores the majority of its formatting. The CATextLayer Class Reference has a number of warnings about what it does in the interests of efficiency.

如果您确实需要绘制到CALayer而不是UIView,则可以创建自己的CALayer子类或委托并在其中进行绘制.

If you really need to draw to a CALayer, not a UIView, you may be able to create your own CALayer subclass or delegate and do the drawing there.

- (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);
}

这篇关于CATextLayer + NSAttributtedString + CTParagraphStyleRef的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 18:31