Byt*_*yte 4 layer ipad ios catextlayer ios6
背景:我在iOS 5中启动了我的项目,并构建了一个带图层的漂亮按钮.我在按钮上添加了一个textLayer,并使用以下代码将其居中:
float textLayerVerticlePadding = ((self.bounds.size.height - fontSize) /2);
textLayer = [[CATextLayer alloc]init];
[textLayer setFrame:CGRectOffset(self.bounds, 0, textLayerVerticlePadding)];
Run Code Online (Sandbox Code Playgroud)
它工作得很好,看起来已经死了,直到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, 0, textLayerVerticlePadding)];
Run Code Online (Sandbox Code Playgroud)
有了这段代码,我每次都会得到一个死角.请注意,这仅HelveticaNeue-Bold在iOS5和iOS6上进行了测试.我不能说其他任何事情.
在iOS 5及之前的版本中,a中的第一个基线CATextLayer始终从边界的顶部向下定位,从CTLineGetTypographicBounds通过CTLine第一行的字符串传递时获得的上升.
在iOS 6中,这不再适用于所有字体.因此,当您定位时,您CATextLayer无法再可靠地决定将其放置在何处以获得正确的视觉对齐.或者你呢?...
首先,CATextLayer暂且不说:在iOS 5中尝试计算出定位行为时,我尝试使用帽子高度的所有组合,来自UIFont的ascender等,最后发现上升CTLineGetTypographicBounds是我需要的.在这个过程中,我发现a)从某些字体上升UIFont ascender,CTFontGetAscent并且与CTLineGetTypographicBounds某些字体不一致,并且b)上升经常是奇怪的 - 要么裁剪重音,要么离开上面的空间.a)的解决方案是知道要使用哪个值.除了通过抵消CATextLayer边界留出足够的空间,如果它可能会有被剪裁的重音,那么除了留出足够的空间之外,没有真正的解决方案.
返回iOS 6.如果您避免使用最严重的违规字体(从6.0开始,可能会有变化),您仍然可以CATextLayer使用其他字体进行编程定位.罪犯是:AcademyEngravedLetPlain,快递,HoeflerText和帕拉提诺 -视觉,这些家庭正确位置(即没有削波)中CATextLayer,但没有的三个上升源给你其中基线被放置的可用指示.Helvetica和.HelveticaNeueUI(又名系统字体)系列在上升时由于基线正确定位UIFont ascender,但是其他上升源不可用.
我做过测试的一些例子.示例文本以不同颜色绘制三次.坐标原点位于灰色框的左上角.黑色文本CTLineDraw通过上升向下偏移绘制CTLineGetTypographicBounds; 透明红色CATextLayer用等于灰色框的边界绘制; 透明蓝色绘制与UIKit NSString添加drawAtPoint:withFont:位于灰色框的原点和与UIFont.
1)表现良好的字体,Copperplate-Light.这三个样本是重合的,给出了栗色,并且意味着所有来源的上升距离足够近.iOS 5和6也是如此.

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

3)iOS 6下的Courier.CATextLayer(红色)现在放置文本,使其不被剪裁,但定位不再与CTLineGetTypographicBounds(黑色)UIFont上升或NSString drawAtPoint:withFont:(蓝色)中使用的上升相匹配.这对于编程定位是不可用的.(AcademyEngravedLetPlain,HoeflerText和帕拉提诺也这样的表现在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, 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4393 次 |
| 最近记录: |