14

I ran into an issue where I needed to animate translating a label vertically the same distance of a textField's text height. In most cases just textField.bounds.heigt but if the textField's height is bigger than the text height it will not be any good for me. So I need to know: How to calculate the line height of the string text from its UIFont?

Regarding the duplicate: There's a little bit different of what I need. that answer(which I've referenced in my answer) get the total height depending on 1) the string 2) the width 3) the font. What I needed is one line height dpending only on the font.

Ismail
  • 2,778
  • 2
  • 24
  • 39
  • 1
    Possible duplicate of [Figure out size of UILabel based on String in Swift](http://stackoverflow.com/questions/30450434/figure-out-size-of-uilabel-based-on-string-in-swift) – TylerH Feb 29 '16 at 17:05
  • It's a little bit different of what I need. that answer(which I've referenced in my answer) get the total height depending on 1) the string 2) the width 3) the font. What I needed is **one line height dpending only on the font** – Ismail Feb 29 '16 at 17:08

3 Answers3

24

UIFont has a property lineHeight:

    if let font = _textView.font {
        let height = font.lineHeight
    }

where font is your font

Natarajan
  • 3,241
  • 3
  • 17
  • 34
Alexandr Kolesnik
  • 1,929
  • 1
  • 17
  • 30
  • 4
    font.lineHeight returns the height of a font. However, a UILabel is always a little higher than the line height – migrant Jul 28 '19 at 03:35
4

I have been searching for a way to do that and find this answer where it has a String extension to calculate the size for the string and a given font. I have modified it to do what I want (get the line height of text written using a font.):

extension UIFont {
    func calculateHeight(text: String, width: CGFloat) -> CGFloat {
        let constraintRect = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let boundingBox = text.boundingRect(with: constraintRect,
                                        options: NSStringDrawingOptions.usesLineFragmentOrigin,
                                        attributes: [NSAttributedStringKey.font: self],
                                        context: nil)
        return boundingBox.height
    }
}

I hope this helps someone looking for it. (may be myself in the future).

some_id
  • 29,466
  • 62
  • 182
  • 304
Ismail
  • 2,778
  • 2
  • 24
  • 39
0

I've used this String extension in the past to draw some text as opposed to creating a UILabel somewhere. I don't like the fact that I can't seem to get the real height of the specific text I want to draw (not every string contains capital letters or characters with descenders, etc.) I've used a couple of enums for horizontal and vertical alignment around the given point. Open to ideas on the vertical height.

public func draw(at pt: CGPoint,
                 font: UIFont? = UIFont.systemFont(ofSize: 12),
                 color: UIColor? = .black,
                 align: HorizontalAlignment? = .Center,
                 vAlign: VerticalAlignment? = .Middle)
{
    let attributes: [NSAttributedString.Key : Any] = [.font: font!,
                                                      .foregroundColor: color!]
    
    let size = self.boundingRect(with: CGSize(width: 0, height: 0),
                                 options: [ .usesFontLeading ],
                                 attributes: [ .font: font! ],
                                 context: nil).size
    var x = pt.x
    var y = pt.y
    if align == .Center {
        x -= (size.width / 2)
    } else if align == .Right {
        x -= size.width
    }
    if vAlign == .Middle {
        y -= (size.height / 2)
    } else if  vAlign == .Bottom {
        y -= size.height
    }
    let rect = CGRect(x: x, y: y, width: size.width, height: size.height)
    draw(in: rect, withAttributes: attributes)
}