我有一个字符串为'LA‘的UILabel。我还有一个在NSAttributedString中具有相同字符的CATextLayer,它被分配给它的string属性。UILabel中的字距调整明显不同于CATextLayer中的字距调整。这是代码。
- (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示例中做错了什么?
发布于 2012-10-07 02:36:52
UIKit通常使用WebKit进行文本呈现(在this crash log)中可见,很可能是出于性能原因)。如果你真的需要超精度,那么有一些使用CoreText作为后端的custom UILabel reimplementations。
EDIT:从iOS7开始,不再是这样的,因为UILabel使用TextKit进行渲染,这也是基于CoreText的。
发布于 2013-03-04 14:44:06
您应该将属性添加到您的NSMutableAttributedString。
对于字距调整:
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:
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):
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);发布于 2012-05-29 13:37:22
与使用UIKit绘制字符串相比,Core Text确实不同,可能是因为它来自Core Foundation,而不是AppKit或UIKit。我确实理解您的要求,即使用标签在字符串上执行复杂的度量工作。对我来说,唯一的解决方案是在属性字符串中匹配UILabel的字距调整,不幸的是,我不知道确切的值,但您可以使用此属性来更改该值kCTKernAttributeName。您还应该注意可能不同的行间。
强制将该值设置为匹配的字距调整,您可以获得正确的行为。如果你想反其道而行之(匹配CT字距调整),你应该做一些数学运算,然后应用于标签一个UIEdgeInset来计算正确的标签。
希望这能有所帮助。
https://stackoverflow.com/questions/10477096
复制相似问题