Figure out size of UILabel based on String in Swift Figure out size of UILabel based on String in Swift ios ios

Figure out size of UILabel based on String in Swift


Use an extension on String

Swift 3

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

and also on NSAttributedString (which is very useful at times)

extension NSAttributedString {    func height(withConstrainedWidth width: CGFloat) -> CGFloat {        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)            return ceil(boundingBox.height)    }    func width(withConstrainedHeight height: CGFloat) -> CGFloat {        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)        let boundingBox = boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, context: nil)            return ceil(boundingBox.width)    }}

Swift 4 & 5

Just change the value for attributes in the extension String methods

from

[NSFontAttributeName: font]

to

[.font : font]


For multiline text this answer is not working correctly. You can build a different String extension by using UILabel

extension String {func height(constraintedWidth width: CGFloat, font: UIFont) -> CGFloat {    let label =  UILabel(frame: CGRect(x: 0, y: 0, width: width, height: .greatestFiniteMagnitude))    label.numberOfLines = 0    label.text = self    label.font = font    label.sizeToFit()    return label.frame.height }}

The UILabel gets a fixed width and the .numberOfLines is set to 0. By adding the text and calling .sizeToFit() it automatically adjusts to the correct height.

Code is written in Swift 3 πŸ”ΆπŸ¦


Heres a simple solution thats working for me... similar to some of the others posted, but it doesn't not include the need for calling sizeToFit

Note this is written in Swift 5

let lbl = UILabel()lbl.numberOfLines = 0lbl.font = UIFont.systemFont(ofSize: 12) // make sure you set this correctly lbl.text = "My text that may or may not wrap lines..."let width = 100.0 // the width of the view you are constraint to, keep in mind any applied margins herelet height = lbl.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height

This handles line wrapping and such. Not the most elegant code, but it gets the job done.