字体在 UILabel 中不合适 - Ascender 或 Descender 被裁剪

Posted

技术标签:

【中文标题】字体在 UILabel 中不合适 - Ascender 或 Descender 被裁剪【英文标题】:Fonts not fitting properly in UILabel - Ascender or Descender cropped 【发布时间】:2014-05-18 19:05:14 【问题描述】:

我进行了广泛的搜索/阅读/测试,但找不到解决此问题的方法。 我从 ios 4.3 开始尝试,但在 iOS7 中仍未解决。

问题是这样的: 大尺寸字体可以在 UILabel 中裁剪其 Ascenders 或 Descenders。 这是直接来自 Xcode 5.1 UI 的屏幕截图(根本没有代码!)显示问题 - 字体大小 300 磅:

如您所见,即使是像 Helvetica Neue(粗体或不粗体)这样的简单字体也会被 Descender 裁剪。 (您看到的是 UIViewController > UIView > UILabel)

如果您尝试此操作然后更改磅值,您会看到字体缩小,最终不会裁剪 Descender。这里又是 160 点:

另请注意,有些字体不会被裁剪,而其他字体会 - 尝试 Noteworthy、Papyrus 或 Savoye LET - 所有这些都是标准 iOS 和字体......

我在这里谈论的是高度 - 我知道我可以使用 adjustsFontSizeToFitWidth=YES 来查看整个长度,并且我也知道我可以使用 sizeToFit,但是既不保证不裁剪 Ascender/下降器。

还请注意,使用 Ascender/Descender 值计算高度无济于事,因为主要问题是字体在绘制时在标签内垂直居中 . (如果是,那将是一个简单的计算。)

所以问题来了:我怎样才能显示尽可能高的字体并确保 Ascender/Descender 不会被裁剪无论使用何种字体

编辑: 我重新阅读了我的问题并意识到我没有正确地问它 - 我能够调整标签的大小以适合字体 - 这不是问题。这是修改后的问题:

如何在 UILabel 中绘制尽可能大的文本并确保它垂直居中,而不裁剪 Ascender 或 Descender?

我可以很容易地算出文本的整体高度,一旦我知道它适合,如何在垂直居中的 UILabel 中绘制它?

例如:在第一个屏幕截图中,文本“Tg”被裁剪,但它很容易足够短以垂直放置在标签中。事实上,如果它正确居中,它可能会更大并且仍然适合。但我知道没有办法将它垂直居中......

【问题讨论】:

【参考方案1】:

我试过了,它解决了我的问题。本质上,字母的高度是上升+下降。这就是标签垂直所需的所有空间。

1. [commentLabel sizeToFit]; //从标签中剪掉不需要的区域

2. [commentLabel setFrame:CGRectMake(commentLabel.frame.origin.x, commentLabel.frame.origin.y + ABS(commentLabel.font.descender), commentLabel.frame.size.width ,commentLabel.font.ascender + ABS(commentLabel.font.descender))];

//**(2)**中的框架调整将标签向下移动了commentLabel.font.descender,因为标签默认是根据它们的实际底线对齐而不是我们在笔记本上使用的实际线,其中下降器从线上垂下来。如果是标签,底线是下降器的下端。

【讨论】:

【参考方案2】:

标签的大小可以根据字符串的长度、使用的字体属性和字体的大小来调整。我经常使用这种方法,并且非常适合这些要求 -

NSString *textWithinLabel = @"Whatever you like, passed from where ever";

CGSize maximumLabelSize = CGSizeMake(300, 1000); //Place your maximum sizes here

//Here I've used Helvetica, though you can pass any font name or font size here to try out
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[[UIFont fontWithName:@"Helvetica" size:15] forKey: NSFontAttributeName];

CGSize newExpectedLabelSize = [textWithinLabel boundingRectWithSize:maximumLabelSize options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;

 CGRect frame = self.yourLabel.frame;
frame.size.height = newExpectedLabelSize.height;
self.yourLabel.frame = frame;

这个例子将改变标签的高度,虽然你也可以用它来改变宽度等等。 这里的stringAttributes是用来计算大小的,不是用来设置属性的。因此,例如,如果您的标签使用 14pts 并且您计算 30pts 的高度,它不会改变字体的高度,它只会增加标签的大小以适应更大的字体大小。如果您希望此方法也更改字体属性,则需要在方法底部添加适当的代码 - self.yourLabel.text.font = ... 等。

我希望这能回答你的问题,

谢谢,吉姆。

【讨论】:

Jeely - 谢谢,但在查看了我的问题后,我认为我需要重新措辞。我能够增加标签的大小以适应字体 - 这不是真正的问题 - 请参阅我的更新。很抱歉造成混乱。

以上是关于字体在 UILabel 中不合适 - Ascender 或 Descender 被裁剪的主要内容,如果未能解决你的问题,请参考以下文章

为啥字符串格式在 UILabel 中不起作用?

UILabel字体大小?

UILabel 在圆形自定义 UIView 中不可见

在 UILabel 中覆盖“文本”在 iOS 6 中不起作用

iOS 10中的UILabel,制作文字字体

MapKit 中的中心位置在 UiLabel 中不可见