How to get the height of a UILabel in Swift?
Asked Answered
A

5

19

I am a beginner in Swift and I am trying to get the height of a label. The label has multiple lines of text. I want to know the total height it occupies on the screen.

Aphelion answered 8/4, 2016 at 20:38 Comment(2)
Dupe: https://mcmap.net/q/121410/-uilabel-heightFender
It depends when you check it. When are you checking it?Windbound
D
20

it's simple, just call

label.bounds.size.height
Distraught answered 8/4, 2016 at 20:43 Comment(7)
I am printing the size on console and getting 0.0 for my label's height. This is what I tried : print(label.bounds.size.height)Aphelion
How is your label set up? If you are using Auto Layout, you will need to create constraints to give the label a height.Hardheaded
I have a vertical stack view and have 3 labels in it. Yes I am using auto layout. But is it not possible to get the default height that the label takes without setting it manually? @HardheadedAphelion
The default height would be 0 until you give it some constraints.Hardheaded
Note that the height might not be set yet if you print it in the initializer or e.g. in viewDidLoad(). Instead you should print the height in viewWillAppear().Roney
@AhmedR, bro could you please take a look at my question #44967483 ?Entrechat
try this Label.frame.heightOrnis
K
23

Swift 4 with extension

extension UILabel{

public var requiredHeight: CGFloat {
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text
    label.attributedText = attributedText
    label.sizeToFit()
    return label.frame.height
  }
}
Klopstock answered 22/6, 2018 at 5:36 Comment(0)
D
20

it's simple, just call

label.bounds.size.height
Distraught answered 8/4, 2016 at 20:43 Comment(7)
I am printing the size on console and getting 0.0 for my label's height. This is what I tried : print(label.bounds.size.height)Aphelion
How is your label set up? If you are using Auto Layout, you will need to create constraints to give the label a height.Hardheaded
I have a vertical stack view and have 3 labels in it. Yes I am using auto layout. But is it not possible to get the default height that the label takes without setting it manually? @HardheadedAphelion
The default height would be 0 until you give it some constraints.Hardheaded
Note that the height might not be set yet if you print it in the initializer or e.g. in viewDidLoad(). Instead you should print the height in viewWillAppear().Roney
@AhmedR, bro could you please take a look at my question #44967483 ?Entrechat
try this Label.frame.heightOrnis
J
10

Updated for Swift 3

func estimatedHeightOfLabel(text: String) -> CGFloat {

    let size = CGSize(width: view.frame.width - 16, height: 1000)

    let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)

    let attributes = [NSFontAttributeName: UIFont.systemFont(ofSize: 10)]

    let rectangleHeight = String(text).boundingRect(with: size, options: options, attributes: attributes, context: nil).height

    return rectangleHeight
}

override func viewDidLoad() {
    super.viewDidLoad()

    guard let labelText = label1.text else { return }
    let height = estimatedHeightOfLabel(text: labelText)
    print(height)
}

enter image description here

Jobyna answered 30/7, 2017 at 10:4 Comment(6)
if you want to use this method for layouting, make sure to return ceil(rectangleHeight), otherwise autolayout might crop off textDelirium
@slashburn can you plz elaborate more what will be the actual problem when we not used return ceil(rectangleHeight)?Jobyna
The overall approach works perfectly. When I tried the code on a UILabel with a longer text, the text got cropped off. Therefore I've used ceil() to get the next biggest integer number and then the content was no longer cropped off.Delirium
@slashburn what do you mean by when using this method for layout make sure to cast the rectHeight as ceil because the text got cropped off? I don't understand how the text got cropped off. I'm using this inside a cell's sizeForItem and sizeForHeader. The textLabel inside the cell sometimes wraps to 2-3 lines and other times it's 1 line only with no wrapping (maybe 2 -3 words instead of a sentence). Both of those get called before the cell is displayed, do I need to use return ceil(rectangleHeight)?Krieger
In my experiments I found that if you specify something like 95.46875 as a height then sometimes auto layout had trouble fitting the text in correctly. Therefore I just round up the number. So 95.46875 gets rounded up to 96 and so I can be sure that there is no pixel issue and that the text will fit in. Don't know if that's the best approach but this worked for meDelirium
@slashburn I forgot to thank you for the reply and explanation. Thanks! :)Krieger
B
3

Swift 5 ioS 13.2 tested 100%, best solution when the UILabel numberOfLines = 0

Note, result is rounded. Just remove ceil() if you don't want it.

If you want to get height -> give storyboard width of UILabel

If you want to get width -> give storyboard height of UILabel

    let stringValue = ""//your label text
    let width:CGFloat = 0//storybord width of UILabel
    let height:CGFloat = 0//storyboard height of UILabel
    let font = UIFont(name: "HelveticaNeue-Bold", size: 18)//font type and size

    func getLableHeightRuntime() -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = stringValue.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
        return ceil(boundingBox.height)
    }

    func getLabelWidthRuntime() -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = stringValue.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
        return ceil(boundingBox.width)
    }
Breathed answered 19/5, 2020 at 8:58 Comment(1)
It working good, However it is not working, when adjustsFontSizeToFitWidth = trueFiorenze
K
1

@iajmeri43's answer Updated for Swift 5

func estimatedLabelHeight(text: String, width: CGFloat, font: UIFont) -> CGFloat {
    
    let size = CGSize(width: width, height: 1000)
    
    let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
    
    let attributes = [NSAttributedString.Key.font: font]
    
    let rectangleHeight = String(text).boundingRect(with: size, options: options, attributes: attributes, context: nil).height
    
    return rectangleHeight
}

To use it:

// 1. get the text from the label
guard let theLabelsText = myLabel.text else { return }

// 2. get the width of the view the label is in for example a cell
// Here I'm just stating that the cell is the same exact width of whatever the collection's width is which is usually based on the width of the view that collectionView is in
let widthOfCell = self.collectionView.frame.width

// 3. get the font that your using for the label. For this example the label's font is UIFont.systemFont(ofSize: 17)
let theLabelsFont = UIFont.systemFont(ofSize: 17)

// 4. Plug the 3 values from above into the function
let totalLabelHeight = estimatedLabelHeight(text: theLabelsText, width: widthOfCell, font: theLabelsFont)

// 5. Print out the label's height with decimal values eg. 95.46875
print(totalLabelHeight)

// 6. as @slashburn suggested in the comments, use the ceil() function to round out the totalLabelHeight
let ceilHeight = ceil(totalLabelHeight)

// 7. Print out the ceilHeight rounded off eg. 95.0
print(ceilHeight)
Krieger answered 9/10, 2018 at 20:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.