首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与CATextLayer不同的UILabel默认字距调整

与CATextLayer不同的UILabel默认字距调整
EN

Stack Overflow用户
提问于 2012-05-07 13:29:56
回答 3查看 1.8K关注 0票数 12

我有一个字符串为'LA‘的UILabel。我还有一个在NSAttributedString中具有相同字符的CATextLayer,它被分配给它的string属性。UILabel中的字距调整明显不同于CATextLayer中的字距调整。这是代码。

代码语言:javascript
运行
复制
- (void)viewDidLoad
{
    [super viewDidLoad];

    // 
    // UILabel
    //
    UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(20, 50, 280, 100)];
    label1.text = @"LA";
    label1.backgroundColor = [UIColor clearColor];
    label1.font = [UIFont fontWithName:@"Futura" size:90.0];
    [self.view addSubview:label1];

    //
    // CATextLayer
    //
    UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(20, 130, 280, 100)];
    label2.backgroundColor = [UIColor clearColor];
    CATextLayer *textLayer = [[CATextLayer alloc] init];
    textLayer.frame = label2.layer.bounds;
    textLayer.contentsScale = [[UIScreen mainScreen] scale];
    [label2.layer addSublayer:textLayer];
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"LA"];
    CTFontRef aFont = CTFontCreateWithName((__bridge CFStringRef)@"Futura", 90.0, NULL);
    [string addAttribute:(NSString*)kCTFontAttributeName value:(__bridge id)aFont range:NSMakeRange(0, [string length])];
    textLayer.string = string;
    [self.view addSubview:label2];
}

以下是结果的an image

为什么这两种方法的字距调整不同?我在CATextLayer示例中做错了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-07 02:36:52

UIKit通常使用WebKit进行文本呈现(在this crash log)中可见,很可能是出于性能原因)。如果你真的需要超精度,那么有一些使用CoreText作为后端的custom UILabel reimplementations

EDIT:从iOS7开始,不再是这样的,因为UILabel使用TextKit进行渲染,这也是基于CoreText的。

票数 3
EN

Stack Overflow用户

发布于 2013-03-04 14:44:06

您应该将属性添加到您的NSMutableAttributedString。

对于字距调整:

代码语言:javascript
运行
复制
    CGFloat characterspacing = 10.0f;
    CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&characterspacing);
    [string addAttribute:(id)kCTKernAttributeName value:(id)num range:NSMakeRange(0 , [string length])];
    CFRelease(num);

如果您还需要行间距,或设置LineBreadMode:

代码语言:javascript
运行
复制
    CTLineBreakMode linebreak = kCTLineBreakByCharWrapping;
    CTParagraphStyleSetting linebreakStyle;
    linebreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode;
    linebreakStyle.valueSize = sizeof(linebreak);
    linebreakStyle.value = &linebreak;

    CTParagraphStyleSetting lineSpaceStyle;
    CGFloat linespacing = self.linesSpacing;
    lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;
    lineSpaceStyle.valueSize = sizeof(linespacing);
    lineSpaceStyle.value =&linespacing;
    CTParagraphStyleSetting settings[ ] ={linebreakStyle,lineSpaceStyle};
    CTParagraphStyleRef style = CTParagraphStyleCreate(settings ,2);
    [string addAttribute:(id)kCTParagraphStyleAttributeName value:(id)style range:NSMakeRange(0 , [string length])];
    CFRelease(style);

最后,您可能需要计算有关字距、行距和LineBreakMode的行数(Linenum):

代码语言:javascript
运行
复制
CTFramesetterRef myframesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
CGMutablePathRef leftColumnPath = CGPathCreateMutable();
CGPathAddRect(leftColumnPath, NULL ,CGRectMake(0 , 0 , Lable.frame.size.width, MAXFLOAT));
CTFrameRef leftFrame = CTFramesetterCreateFrame(myframesetter,CFRangeMake(0, 0), leftColumnPath , NULL);
CFArrayRef lines = CTFrameGetLines(leftFrame);
linenum = (int)CFArrayGetCount(lines);
CFRelease(myframesetter);
CFRelease(leftFrame);
CGPathRelease(leftColumnPath);
票数 1
EN

Stack Overflow用户

发布于 2012-05-29 13:37:22

与使用UIKit绘制字符串相比,Core Text确实不同,可能是因为它来自Core Foundation,而不是AppKitUIKit。我确实理解您的要求,即使用标签在字符串上执行复杂的度量工作。对我来说,唯一的解决方案是在属性字符串中匹配UILabel的字距调整,不幸的是,我不知道确切的值,但您可以使用此属性来更改该值kCTKernAttributeName。您还应该注意可能不同的行间。

强制将该值设置为匹配的字距调整,您可以获得正确的行为。如果你想反其道而行之(匹配CT字距调整),你应该做一些数学运算,然后应用于标签一个UIEdgeInset来计算正确的标签。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10477096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档