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

时间:2014-01-14 09:56:09

标签: ios objective-c fonts autolayout

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

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

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

enter image description here

3 个答案:

答案 0 :(得分:4)

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

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

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

的内容

答案 1 :(得分:3)

谢谢Abhinit,以获得答案。

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

来自Wikipedia的此图片显示了字体的不同大小部分。

enter image description here

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

我们假设您有label个文字,其中包含#34; 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中的否定插入执行此操作(例如here,但使用insets = {-ascenderDelta, 0, font.descender, 0})。但是如果你有的话,那将会裁掉任何上升/下降器。我宁愿在不裁剪任何可能上升的情况下与帽子对齐。

答案 2 :(得分:2)

我有同样的问题并通过继承UILabel并更改其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)