Search code examples
iosswiftuitableviewautolayoutuitextview

UITextview height in UITableview swift


Im facing a problem while setting up UITextview in UITableViewCell. As the function heightforrowatindexpath is running before cellforrowatindexpath so I cannot calculate the size of content of UITextview.

Im calculating the size by simply textview.contentSize.height in cellforrowatindexpath function.

Im basically want UITextview contentHeight fit in UITableViewCell so no scroll is visible for every UITextView and it will show full content by increasing the height of UITableViewCell.

I also a UILabel just above the UITextView in UITableViewCell and I tried to set contraints for both but unable to achieve my goal.

How can I calculate the size of UITableViewCell dynamically in following function:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

}

P.S: Is it possible to use increase the UITableViewCell height a little bit according to device height, using auto layout or some technique else.


Solution

  • You can just pass your textView with the content in order to calculate the height of the textView

    func calculateHeight(textView:UITextView, data:String) -> CGRect {
    
        var newFrame:CGRect! 
    
        // I was using the HTML content here. If your content is not HTML you can just pass the stringValue to your textView
        do {
            let attr = try NSAttributedString(data: html.dataUsingEncoding(NSUTF16StringEncoding)!, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType], documentAttributes: nil)
            textView.attributedText = attr
    
        }catch {
            //Handle Exceptions
        }
    
        let fixedWidth = textView.frame.size.width
        textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        newFrame = textView.frame
        newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
        print("height \(newFrame.height)")
        return newFrame
    }
    

    You can call this method in your heightForRowAtIndex so that in return you can get a new updated frame from which you can fetch the new updated height.

    Make sure to keep scrollEnabled as false of your cell's textView in cellForRowAtIndexPath

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
            //Cell making here......
    
            cell.yourTextView.scrollEnabled = false
            return cell  
        }
    }