14

I am trying to layout text on a UIView.

(The yellow area is the frame of the UILabel with a background color).

When I use sizeWithFont I get this, which has a very large space above the letter:

p with sizeWithFont

When I use font.pointSize i get this for "i" which is good-

p with font.pointSize

BUT When i use it for "p" I get the precise height but the letter is drawn in the bottom and cropped.

p with font.pointSize

**How can i get get the glyph only centered in the frame ? **

Thanks

Shani

Community
  • 1
  • 1
shannoga
  • 19,649
  • 20
  • 104
  • 169

3 Answers3

23

There are a lot of properties on UIFont to help in this situation:

  • pointSize
  • ascender
  • descender
  • capHeight
  • xHeight
  • lineHeight
Jeff Kelley
  • 19,021
  • 6
  • 70
  • 80
  • 3
    It would be nice to have a picture so it is obvious what they all are defined as. For instance, does pointSize == ascender + descender and is ascender >= capHeight? – Matt Aug 14 '14 at 01:53
  • 8
    @Matt, it's an oldy, but I find the image on https://www.cocoanetics.com/2010/02/understanding-uifont/ very helpful. – Roy Apr 08 '15 at 09:14
  • 1
    these font properties often lie - not sure if it’s iOS or the fonts themselves - i’m looking at a font now, where the lineHeight is identical to pointSize (very odd), and ascender - descender + leading is about 10% less than required bounding box to enclose the whole word. – Roy Lovejoy Apr 12 '18 at 00:37
3

Try moving the text upwards by font.ascender - font.capHeight. Shrinking the height of a UILabel will likely clip its contents, so it is better to adjust the label's y position instead of resizing.

The following code sample explains the computation I used:

// in UILabel subclass:
- (CGFloat) topPadding
{
    // ascender = height from baseline to top of label (including top padding)
    // capHeight = height of a capital letter = ascender - top padding
    //  -> top padding = ascender - capHeight
    return self.font.ascender - self.font.capHeight;
}
Rolf Hendriks
  • 411
  • 4
  • 8
3

You could convert the UILabel to a UIImage with a "printscreen" sort of function and then check the the pixels one by one (with for instance: How to get pixel data from a UIImage (Cocoa Touch) or CGImage (Core Graphics)?) and 'calculate' the left top en right bottom.

Community
  • 1
  • 1
basvk
  • 4,437
  • 3
  • 29
  • 49
  • it's definitely not necessary to convert a label to an UIImage, the answer provided by Jeff Kelly is better. There are many attributes that can help you define the exact height of a UILabel – Bob de Graaf Sep 28 '12 at 09:30
  • 2
    I disagree. For some fonts the height per capital (capHeight) differs per character (see http://bit.ly/OtdxOe). Other @properties of the `UIFont` class have the same 'problems'. I've had a similar problem when developing something in flash/as3. "Counting pixels" did it for me at the end. – basvk Sep 28 '12 at 09:37