来自iOS 6的CATextLayer上的不需要的垂直填充

来自iOS 6的CATextLayer上的不需要的垂直填充,第1张

概述背景:我在iOS 5中启动了我的项目,并构建了一个带图层的漂亮按钮.我在按钮上添加了一个textLayer,并使用以下代码将其居中: float textLayerVerticlePadding = ((self.bounds.size.height - fontSize) /2); textLayer = [[CATextLayer alloc]init]; [textLayer 背景:我在iOS 5中启动了我的项目,并构建了一个带图层的漂亮按钮.我在按钮上添加了一个textLayer,并使用以下代码将其居中:

float textLayerVerticlepadding = ((self.bounds.size.height - FontSize) /2);    textLayer = [[CATextLayer alloc]init];    [textLayer setFrame:CGRectOffset(self.bounds,textLayerVerticlepadding)];

它工作得很好,看起来已经死了,直到iOS 6.

问题:iOS 6在textLayer中最顶层边界和文本之间添加了一个空格(填充).这扰乱了上面的计算.有没有办法确保iOS 6没有?因为我想支持iOS 5和6(对于那些喜欢谷歌地图的人).

图片:
这个是iOS 5,红色是textLayer的背景(使其更加明显)

这个是iOS 6

更新:虽然我确定下面的所有答案都是以他们自己的方式是正确的,但我发现这个帖子是第一个最简单的方法来执行它. HelveticaNeue为iOS5和iOS6留下了一点空间,与Helvetica不同,它在iOS5顶部没有空间,在iOS6中没有空间.

更新2:再玩一下,找出小空间的大小.没有详细说明,空间是字体大小的1/6.所以为了弥补它,我写道

float textLayerVerticlepadding = ((self.bounds.size.height - FontSize) /2) - (FontSize/6);[textLayer setFrame:CGRectOffset(self.bounds,textLayerVerticlepadding)];

有了这段代码,我每次都会得到一个死角.请注意,这仅在iOS5和iOS6上使用HelveticaNeue-Bold进行测试.我不能说其他任何事情.

解决方法 在iOS 5及之前的版本中,CATextLayer中的第一个基线始终位于边界的顶部,通过CTlineGetTypographicBounds获得的上升,当传递使用第一行的字符串创建的CTline时.

在iOS 6中,这不再适用于所有字体.因此,当您定位CATextLayer时,您无法再可靠地决定将其放置在何处以获得正确的视觉对齐.或者你呢? …

首先,旁白:在iOS 5中尝试计算出CATextLayer的定位行为时,我尝试使用帽子高度的所有组合,来自UIFont的ascender等,最后发现CTlineGetTypographicBounds的上升是我需要的.在这个过程中,我发现a)来自UIFont上升器,CTFontGetAscent和CTlineGetTypographicBounds的上升对于某些字体是不一致的,并且b)上升经常是奇怪的 – 要么裁剪重音或者离开上面的空间. a)的解决方案是知道要使用哪个值. b)除了通过抵消CATextLayer边界而留下足够的空间,如果它可能会有被剪裁的重音符号,则没有真正的解决方案.

返回iOS 6.如果您避免使用最严重的违规字体(从6.0开始,可能会有变化),您仍然可以使用其他字体对CATextLayer进行编程定位.犯罪者是:AcademyEngravedLetPlain,CourIEr,HoeflerText和Palatino–在视觉上,这些家族在CATextLayer中正确定位(即没有剪裁),但三个上升源中没有一个为您提供基线放置位置的可用指示. Helvetica和.HelveticaNeueUI(又名系统字体)系列在UIFont ascender给出的上升时正确定位基线,但其他上升源不可用.

我做过测试的一些例子.示例文本以不同颜色绘制三次.坐标原点位于灰色框的左上角. CTlineDraw从CTlineGetTypographicBounds上升向下绘制黑色文本;透明红色由CATextLayer绘制,边界等于灰色框;使用UIKit Nsstring绘制透明蓝色drawAtPoint:withFont:位于灰色框的原点和UIFont.

1)表现良好的字体,copperplate-light.这三个样本是重合的,给出了栗色,并且意味着所有来源的上升距离足够近. iOS 5和6也是如此.

2)iOS下的CourIEr 5. CATextLayer将文本定位得太高(红色),但CTlineGetTypographicBounds(黑色)上升的CTlineDraw与CATextLayer定位匹配 – 所以我们可以从那里放置并更正. Nsstring drawAtPoint:withFont :(蓝色)放置文本而不剪裁. (Helvetica和.HelveticaNeueUI在iOS 6中表现如此)

3)iOS 6下的CourIEr.CATextLayer(红色)现在放置文本以使其不被剪裁,但定位不再与CTlineGetTypographicBounds(黑色)或Nsstring drawAtPoint:withFont:(blue)中使用的UIFont ascender匹配.这对于编程定位是不可用的. (AcademyEngravedLetPlain,HoeflerText和Palatino在iOS 6中也表现得像这样)

希望这有助于避免我经历的浪费时间的一些时间,如果你想深入了解,请玩这个:

- (Nsstring*)reportInconsistentFontAscents{    NSMutableString*            results;    NSMutableArray*             FontnameArray;    CGfloat                     FontSize = 28;    Nsstring*                   fn;    Nsstring*                   sample = @"Éa3Çy";    CFRange                     range;    NSMutableAttributedString*  mas;    UIFont*                     uiFont;    CTFontRef                   ctFont;    CTlineRef                   ctline;    CGfloat                     uif_ascent;    CGfloat                     ctFont_ascent;    CGfloat                     ctline_ascent;    results = [NSMutableString stringWithCapacity: 10000];    mas = [[NSMutableAttributedString alloc] initWithString: sample];    range.location = 0,range.length = [sample length];    FontnameArray = [NSMutableArray arrayWithCapacity: 250];    for (fn in [UIFont familynames])        [FontnameArray addobjectsFromArray: [UIFont FontnamesForFamilyname: fn]];    [FontnameArray sortUsingSelector: @selector(localizedCaseInsensitiveCompare:)];    [FontnameArray addobject: [UIFont systemFontOfSize: FontSize].Fontname];    [FontnameArray addobject: [UIFont italicSystemFontOfSize: FontSize].Fontname];    [FontnameArray addobject: [UIFont boldSystemFontOfSize: FontSize].Fontname];    [results appendString: @"Font name\tUIFA\tCTFA\tCTLA"];    for (fn in FontnameArray)    {        uiFont = [UIFont FontWithname: fn size: FontSize];        uif_ascent = uiFont.ascender;        ctFont = CTFontCreateWithname((CFStringRef)fn,FontSize,NulL);        ctFont_ascent = CTFontGetAscent(ctFont);        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)mas,range,kCTFontAttributename,ctFont);        ctline = CTlineCreateWithAttributedString((CFAttributedStringRef)mas);        ctline_ascent = 0;        CTlineGetTypographicBounds(ctline,&ctline_ascent,0);        [results appendFormat: @"\n%@\t%.3f\t%.3f\t%.3f",fn,uif_ascent,ctFont_ascent,ctline_ascent];        if (fabsf(uif_ascent - ctFont_ascent) >= .5f // >.5 can round to pixel diffs in display         || fabsf(uif_ascent - ctline_ascent) >= .5f)            [results appendString: @"\t*****"];        CFRelease(ctline);        CFRelease(ctFont);    }    [mas release];    return results;}
总结

以上是内存溢出为你收集整理的来自iOS 6的CATextLayer上的不需要的垂直填充全部内容,希望文章能够帮你解决来自iOS 6的CATextLayer上的不需要的垂直填充所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1081409.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存