0

I got a UITableView with custom UITableViewCells. Autolayout is off. The UITableViewCell contains a UILabel and a UITextView. The UITextView is filled with text that vary in length. how can i dynamically adjust the height of the UITextView? I tried it with this function from awakeFromNib and after the text is set but nothing changed.

  func adjustHeight(theTextView: UITextView) {

    let contentSize = theTextView.sizeThatFits(theTextView.bounds.size)
    var frame = theTextView.frame
    frame.size.height = contentSize.height
    theTextView.frame = frame

    let aspectRatioTextViewConstraint = NSLayoutConstraint(item: theTextView, attribute: .height, relatedBy: .equal, toItem: theTextView, attribute: .width, multiplier: theTextView.bounds.height/theTextView.bounds.width, constant: 1)
    theTextView.addConstraint(aspectRatioTextViewConstraint)
}
elpatricko
  • 456
  • 4
  • 17
  • You wrote that autolayout is off, but you add it manually in code? What do you mean? – Roman Podymov Aug 02 '17 at 13:14
  • Set these properties. tableView.RowHeight = UITableView.AutomaticDimension; tableView.EstimatedRowHeight = 160f; // as per your cell. Calculate height for textview. as in this link: https://stackoverflow.com/a/25158206/1242673 apply calculated height to textview. – Aadil Ali Aug 02 '17 at 13:18
  • @RomanPodymov i did ? sorry i'm new to iOS development and got the task to make a textview resize itself from content. And i was told autolayout is off. – elpatricko Aug 02 '17 at 13:21
  • @elpatricko did you tried example I added to my answer? – Roman Podymov Aug 06 '17 at 20:43
  • yes. the error i had was due my newbieness in iOS. the TextView was simply to big for the container an the new line was not show... stupid me. – elpatricko Aug 07 '17 at 09:32

2 Answers2

0

Try this

yourTextView.numberOfLines = 0

This will break the text to lines if the text is too long.

If this does not suit you and you want it 1 line only, then add this line after setting the text (or in the delegate function of the textView).

yourTextView.sizeThatFits(yourFrame)

This will make the text smaller to fit the the frme you specified for it.

Hope this helps!

Mohammad Bashir Sidani
  • 1,941
  • 1
  • 9
  • 14
0

I can give you an example that can solve your problem. I use SnapKit https://github.com/SnapKit/SnapKit to update constraints of UIView. This is an example of UIViewController where you want to show your table:

class ViewController: UIViewController {

    private var tableView : UITableView = {

        let tabView = UITableView.init(frame: CGRect.zero)
        tabView.register(TableViewCell.self, forCellReuseIdentifier: "cell")
        return tabView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.dataSource = self
        self.tableView.delegate = self
        self.view.addSubview(self.tableView)
    }

    override func updateViewConstraints() {

        self.tableView.snp.remakeConstraints { (maker) in

            maker.edges.equalTo(self.view) // your table will have the same frame as your view
        }

        super.updateViewConstraints()
    }
}

In the first extension we will put all methods for UITableViewDelegate:

extension ViewController : UITableViewDelegate {

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {

        return 200.0 // any value different from zero. 200 is an example. This value must be easy-to-calculate. 
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return UITableViewAutomaticDimension // tells system that rows will be resized automatically
    }
}

In the second extension there are methods for UITableViewDataSource (just generating some random data):

extension ViewController : UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 20
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
        cell.setup(labelText: "Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label Label ", textViewText: "Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text ")
        return cell
    }
}

And class of cell that contains UILabel and UITextView:

class TableViewCell: UITableViewCell {

    private var label : UILabel = {

        let resultLabel = UILabel.init(frame: CGRect.zero)
        resultLabel.numberOfLines = 0 // If numberOfLines in 0 system will automatically set real number of lines
        return resultLabel
    }()

    private var textView : UITextView = {

        let resultTextView = UITextView.init(frame: CGRect.zero)
        resultTextView.isScrollEnabled = false // disable scroll and editing just for example
        resultTextView.isEditable = false
        return resultTextView
    }()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.contentView.addSubview(self.label)
        self.contentView.addSubview(self.textView)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setup(labelText:String, textViewText:String) {

        self.label.text = labelText
        self.textView.text = textViewText
        self.setNeedsUpdateConstraints()
    }

    override func updateConstraints() {

        self.label.snp.remakeConstraints { (maker) in

            maker.left.equalTo(self.contentView.snp.left)
            maker.right.equalTo(self.contentView.snp.right)
            maker.top.equalTo(self.contentView.snp.top)
            maker.bottom.equalTo(self.textView.snp.top)
        }
        self.textView.snp.remakeConstraints { (maker) in

            maker.left.equalTo(self.contentView.snp.left)
            maker.right.equalTo(self.contentView.snp.right)
            maker.bottom.equalTo(self.contentView.snp.bottom)
        }
        super.updateConstraints()
    }
}
Roman Podymov
  • 3,416
  • 3
  • 28
  • 49