垂直居中UILabel时忽略Ascender和Descender?

我正在使用AutoLayout将一些标签放在单元格的垂直中心。 文本是全部大写的,但是有问题的UILabel ,即使应用了sizeToFit ,也会在文本下方留下空间,这看起来很像字母上的尾部,例如小写的y,p和q 。 因为我是垂直居中的,所以这会导致偏移并且意味着文本看起来比应该做的高几个像素。

另一个问题可能是:我可以根据字体是否包含使用上升器或下降器的任何字符来智能地调整其垂直中心吗?

例如,字符串“abbaba”不需要下降器,而字符串“oyyoyo”不需要上升器。 全部大写字符串也不需要下降器。 如果我垂直居中“oyyoyoyo”它会显得太低。

在此处输入图像描述

谢谢, Abhinit ,你的回答。

我也在寻找这个,所以我想在这里发布您需要的确切限制,以便根据自己的喜好调整文本。

来自维基百科的图像显示了字体的不同大小部分。

在此处输入图像描述

因此,根据您是否要与上boost度,上限高度,x高度,基线或下降高度对齐,有多种方法可以对齐标签。

假设您有一个label其中包含像“HELLO”这样的大写字母,并且您希望与viewAbove对齐以限制高度并与viewBelow对齐到基线。

你会这样做:

 let font = label.font let ascenderDelta = font.ascender - font.capHeight LayoutHelper() .addViews([ "label":label, "viewAbove":viewAbove, "viewBelow":viewBelow ]) .withMetrics(["ascenderDelta":ascenderDelta]) .addConstraints([ // -- Here the constraints to align to cap height -- "X:label.top == viewAbove.bottom - ascenderDelta", "X:label.baseline == viewBelow.top", ...other constraints... ]) 

注意:在示例中我使用的是实用程序类LayoutHelper ,但我希望这个想法很清楚。

关于“自动对齐”标签:

我会考虑制作一个“智能”标签,根据它是否包含下降器,上升器,帽子等,调整到适当的线。

你可以在drawTextInRect使用负插入来实现它(就像这里一样,但是,例如,使用insets = {-ascenderDelta, 0, font.descender, 0} )。 但是如果你有的话,那将会裁掉任何上升/下降器。 我宁愿在不裁剪任何可能的上升的情况下与帽子对齐。

您可以在UIFont上使用’capHeight’和’xHeight’属性来获取正确的高度,并使用它来调整UILabel的大小。

当然,这假设您确定字符串是仅小写还是大写。 如果没有,那么你可以在UILabel上覆盖setText,并在每次调用函数时进行检查。

我还想到深入研究CoreText并实现类似这样的东西http://www.zsiegel.com/2012/10/23/Core-Text-Calculating-line-heights/

我遇到了同样的问题并通过inheritanceUILabel并更改其draw方法来解决它:

 - (void)drawRect:(CGRect)rect { CGRect capCenteredRect = CGRectMake(rect.origin.x, (self.font.leading-self.font.capHeight)*0.5f, rect.size.width, rect.size.height); [super drawTextInRect:capCenteredRect]; } 

在我的情况下,我需要居中到帽子,因为UILabel的垂直居中总是有些像素关闭。 如果您需要使用下行器垂直居中于小写字母,可以将矩形更改为:

 CGRectMake(rect.origin.x, (self.font.leading-self.font.xHeight)*0.5f+self.font.descender, rect.size.width, rect.size.height)