Fonts not fitting properly in UILabel - Ascender or Descender cropped

纵饮孤独 提交于 2019-12-24 05:14:12

问题


I've done extensive searching/reading/testing and cannot find a solution to this problem. I've tried since iOS 4.3 and it's still not resolved in iOS7.

The problem is this: Fonts at large sizes can have their Ascenders or Descenders cropped in a UILabel. Here's a screenshot directly from the Xcode 5.1 UI (no code at all!) showing the problem - font size 300 points:

As you can see, even a simple font like Helvetica Neue (bold or not) has it's Descender cropped. (You're seeing UIViewController > UIView > UILabel)

If you try this and then change the point size you'll see the font scale down, and eventually the Descender will not be cropped. Here it is again at 160 points:

Notice also that some fonts do not get cropped and others do - try Noteworthy, or Papyrus, or Savoye LET - all of which are standard iOS & fonts....

I'm talking about Height here - I know I can use adjustsFontSizeToFitWidth=YES to see the entire length, and I also know I can use sizeToFit, however neither guarantees no cropping of the Ascender/Descender.

Notice also that calculating the height using Ascender/Descender values does not help as the main issue is that the font is not centered vertically within the label when it is drawn. (If it were, it would be a simple calculation.)

So here is the question: How can I show a font as tall as possible and be assured that the Ascender/Descender is not cropped regardless of the font used?

EDIT: I re-read my question and realized I did not ask it properly - I'm able to resize the label to fit the font - that's not the problem. Here's the revised question:

How can I draw text in a UILabel as large as possible and be assured that it is centered vertically, with no cropping of the Ascender or Descender?

I can easily figure out the overall height of the text, and once I know it will fit, how can draw it in the UILabel vertically centered?

For Example: In the first screenshot, the text "Tg" is cropped, but it is easily short enough to fit vertically in the label. In fact, it could be even larger and still fit if it were properly centered. But I know of no way to center it vertically...


回答1:


The size of the label can be sized according the length of the string, the font attribute used and the size of the font. I use this method a lot and works great for such requirements -

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;

This example will change the height of the label, though you can use it to change width too etc. The stringAttributes here are used to calculate the size, not to set the attributes. So for example, if your label is using 14pts and you calculate the height for 30pts, it won't change the height of the font, it will only increase the size of the label to accommodate the larger font size. If you want this method to also change the font attributes, you would need to add the appropriate code at the bottom of the method - self.yourLabel.text.font = ... etc.

I hope this answers your question,

Thanks, Jim.




回答2:


I tried this and it solved my problem. Essentially, the height of the letter is Ascent+Descent. So that's all the space the label needs vertically.

1. [commentLabel sizeToFit]; //To trim out the unwanted area from the label

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))];

//The frame adjustment in **(2)**moves the label down by commentLabel.font.descender because the label by default is aligned based on their actual bottom line instead of the actual line we use on notebooks, where the descender hangs down from the line. In case of a label the bottom line is the lower tip of the descender.



来源:https://stackoverflow.com/questions/22897158/fonts-not-fitting-properly-in-uilabel-ascender-or-descender-cropped

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!