0

I am using the below UILabel extension method to calculate the number of actual lines in the UILabel. However, I see that it always returns more than the actual number of lines. Moreover, the excess number of lines it returns is not the same always. So, I cannot subtract it with a fixed constant before using the value. Any thoughts of what is wrong here. I have already looked at the solutions posted in stack overflow but they did not help either.

extension UILabel {
    var maxNumberOfLines: Int {
        guard let text = text, let font = font else {
            return 0
        }
        let charSize = font.lineHeight
        let textSize = (text as NSString).boundingRect(
        with: CGSize(width: frame.width, height: .greatestFiniteMagnitude),
        options: .usesLineFragmentOrigin,
        attributes: [.font: font],
            context: nil)
        let linesRoundedUp = Int(ceil(textSize.height/charSize))
        return linesRoundedUp
    }

}
Reshma
  • 233
  • 2
  • 10
  • Take a look at this: https://stackoverflow.com/questions/28108745/how-to-find-actual-number-of-lines-of-uilabel One of the answers makes mention of the need to use layoutIfNeeded() if you are using auto layout. – rs7 May 17 '20 at 22:39
  • Used layoutIfNeeded() but that did not make a difference either. BTW I am using label in a tableview cell. Wondering if that makes any difference or needs any other change. – Reshma May 18 '20 at 05:16
  • Did you use it at the beginning of your block of code? Before you did all the calculations. Even if the label is in a cell, it shouldn't make a difference. – rs7 May 18 '20 at 16:00
  • I am trying to calculate the max number of lines in cellForRow at indexpath delegate method after setting the label text. Since the label has not yet been positioned in the tableview cell yet, it probably does not have the final width at that point and hence the calulcation is going wrong. – Reshma May 18 '20 at 19:19
  • For your question. Yes I added layoutifNeeded() before the calculation. – Reshma May 18 '20 at 19:39

1 Answers1

0

Since I was trying to find the number of lines for UILabel in cell for row at index path delegate method, I was getting wrong result as the UILabel would not be laid out in the tableview cell yet. I used UIScreen.main.bounds - some offset in place of label width for number of lines calculation and that solved the issue.

To be precise, I used

extension UILabel {
    var maxNumberOfLines: Int {
        guard let text = text, let font = font else {
            return 0
        }
        let charSize = font.lineHeight
        let textSize = (text as NSString).boundingRect(
        with: CGSize(width: UIScreen.main.bounds.width - SOMEOFFSET, height: .greatestFiniteMagnitude),
        options: .usesLineFragmentOrigin,
        attributes: [.font: font],
            context: nil)
        let linesRoundedUp = Int(ceil(textSize.height/charSize))
        return linesRoundedUp
    }

}
Reshma
  • 233
  • 2
  • 10