4

When setting some string value to the text attribute of a UILabel like

var a : UILabel
a.text = "Variable length string"

autolayout resizes it using the constraints font size, label number of lines etc.

The question is, if I needed to get the size of that label so that I can ( for example ) decide how high a tablecell that includes this label should be, at what point should I do this successfully?

Trying to figure this out without using UITableviewAutomaticDimension.

EDIT: The answer posted as a possible duplicate bears some resemblence. However, my main confusion is as to where I can extract the height of the UILabel successfully and with certainty.

It has been many times that I have tried to get a view's size but the value I get back is not accurate and need to resort to using viewDidLayoutSubviews() in some form. I guess I don't understand the order of which things happen in the layout very well. And it seems to be different for viewDidLoad() and awakeFromNib() too but I might be mistaken about this.

If anyone could point me to the right direction in understanding this i would be grateful

Return-1
  • 1,953
  • 1
  • 12
  • 44
  • 1
    Possible duplicate of [Adjust UILabel height to text](http://stackoverflow.com/questions/25180443/adjust-uilabel-height-to-text) – tbilopavlovic Mar 24 '17 at 08:56

1 Answers1

2

Try implementing the following method in your ViewController with the tableView:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
             return HeightCalculator.height(with: text, inViewController: self)
}

Then add the following class:

import UIKit

class HeightCalculator {
    let title: String
    let viewController: UIViewController

    class func height(with title: String, inViewController viewController: UIViewController) -> CGFloat {
        let calculator = HeightCalculator(title: title, viewController: viewController)

        return calculator.height
    }

    init(title: String, viewController: UIViewController) {
        self.title = title
        self.viewController = viewController
    }

    var height: CGFloat {
        let contentHeight = title.heightWithConstrainedWidth(width: defaultWidth, font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.title1))
    }
}

You need the following extension on your String to get the height:

import UIKit

extension String {
    func heightWithConstrainedWidth(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 boundingBox.height
    }
}

Use heightForRowAt to calculate the height, the calculator class calculating it (contentHeight) and the extension to get the height. You can adjust the calculator class to pass the font in so it can use this font to pass it to the heightWithConstrainedWidth method.

Hapeki
  • 2,047
  • 1
  • 15
  • 34