Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a UITableView cell dynamically change its height while user is typing?

I am currently working on a feature for dynamically changing a UITableView cell's height while typing. So, if the user has typed in a item that extends the current max width for a cell, then a the cell's height should increase. My specialized TableViewCell contains a TextView and an UILabel and is also, connected to another cell below it. So, there is a TableView with two TableViewCells within that one TableView. I've been trying to experiment ways that it could be solved but nothing has worked so far. Does anyone have any conceptual ideas to get it done?

like image 311
user3681456 Avatar asked Oct 04 '17 20:10

user3681456


1 Answers

First set your tableView rowHeight to UITableViewAutomaticDimension, in your table view cell add UITextView with top, leading, bottom and trailing constraints. Set textView.isEditable to true and textView.isScrollEnabled to false, then implement textView delegate method textViewDidChange. When text changes you need to report to view controller to update the tableview, one way is by delegation. Implement your table view cell delegate in your view controller, from where you'll call tableView.beginUpdates() and tableView.endUpdates(). That's it. Below is a tested and working example.

your view controller:

import UIKit
class ViewController: UIViewController, UITableViewDataSource, ExpandingTableViewCellDelegate {

    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.register(UINib(nibName: "ExpandingTableViewCell", bundle: nil), forCellReuseIdentifier: "ExpandingTableViewCellIdentifier")
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandingTableViewCellIdentifier", for: indexPath) as! ExpandingTableViewCell
        cell.delegate = self
        return cell
    }

    // Expanding teable view cell delegate
    func didChangeText(text: String?, cell: ExpandingTableViewCell) {
        tableView.beginUpdates()
        tableView.endUpdates()
    }
}

your cell:

import UIKit
protocol ExpandingTableViewCellDelegate: class {
    func didChangeText(text: String?, cell: ExpandingTableViewCell)
}

class ExpandingTableViewCell: UITableViewCell, UITextViewDelegate {
    @IBOutlet weak var textView: UITextView!
    weak var delegate: ExpandingTableViewCellDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

        textView.delegate = self
        textView.isEditable = true
        textView.text = "Start typing: ..."
        textView.isScrollEnabled = false
    }

    func textViewDidChange(_ textView: UITextView) {
        delegate?.didChangeText(text: textView.text, cell: self)
    }
}

Example project is here: https://github.com/bavarskis/ExpandingTableViewCell.git

like image 160
Au Ris Avatar answered Sep 27 '22 17:09

Au Ris