get height of dynamic textViews in tableView without using automatic dimensions using swift

103 views Asked by At

I want to calculate the height of my textView's in a tableView dynamically to use in heightForRowAt. I DO NOT want to use automatic dimensions as it often messes up my scrolling in containerViews.

Presently I am instantiating a textView for every cell, adding the text and getting the height using:

var textViewForCellHeight = UITextView()
textViewForCellHeight.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)

textViewForCellHeight.frame = CGRect(x: 0, y: 0, width: self.tableView.frame.size.width - cellHorizontalPadding - tableView.safeAreaInsets.left - tableView.safeAreaInsets.right, height: 0)
textViewForCellHeight.text = myString
textViewForCellHeight.sizeToFit()
return textViewForCellHeight.frame.size.height

Using this in heightForRowAt works fine and gives the correct height for the cell, but it expensive and slows down the tableView considerably. Is there a more efficient way to get the height of the tableView cell's dynamically with a textView?

2

There are 2 answers

0
Datt Patel On

Try this code:

 func cellHeight(withTxt string: String) -> Float {
        let textRect: CGRect = string.boundingRect(with: CGSize(width: self.view.frame.width/* Preferred textView Width */, height: CGFloat(MAXFLOAT)), options: ([.usesLineFragmentOrigin, .usesFontLeading]), attributes: [.font: UIFont(name: "Helvetica Neue", size: 17)!], context: nil)
        let requiredSize: CGSize = textRect.size
        //finally u return your height
        return Float(requiredSize.height)
 }
0
Parth Barot On

You can simply pass your string in this function and you will get dynamic height according to your string.

 func calculateHeight(inString:String) -> CGFloat
{
    let messageString = input.text
    let attributes : [NSAttributedStringKey : Any] = [NSAttributedStringKey(rawValue: NSAttributedStringKey.font.rawValue) : UIFont.systemFont(ofSize: 15.0)]

    let attributedString : NSAttributedString = NSAttributedString(string: messageString!, attributes: attributes)

    let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

    let requredSize:CGRect = rect
    return requiredSize.height
}