Search code examples
iosswiftswift3autolayouttableview

iOS static table auto resize based on textView


I have Text views inside a static table. I want them to resize when there is need for a line break. How do i do this? This is my code so far.

 override func viewDidLoad() {
    super.viewDidLoad()

    table.estimatedRowHeight = 40.0 // Replace with your actual estimation
    table.rowHeight = UITableViewAutomaticDimension


    // Tap to dismiss keyboard
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(EditInfoViewController.dismissKeyboard))
    view.addGestureRecognizer(tap)


}


func dismissKeyboard() {
    view.endEditing(true)
    // Save data
}



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

override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

enter image description here


Solution

  • Swift 3 & Xcode 8.3.2

    Use UILabel instead of UITextView, and set numberOfLine = 0, so it will automatic resize according to its content

    or

    if you want to keep UITextView instead UILabel, here is the code

    class YourClass: UITableViewController, UITextViewDelegate {
    
        var yourCustomCell: UITableViewCell = UITableViewCell()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            table.estimatedRowHeight = 40.0 // Replace with your actual estimation
            table.rowHeight = UITableViewAutomaticDimension
    
    
            // Tap to dismiss keyboard
            let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(EditInfoViewController.dismissKeyboard))
            view.addGestureRecognizer(tap)
    
            // Add tableView delegate
            tableView.dataSource = self
            tableView.delegate = self
    
            // Add textView delegate
            yourTextView.delegate = self
    
    
        }
        // Text view delegate, dont forget to add yourTextView.delegate = self in viewDidLoad
        func textViewDidChange(_ textView: UITextView) {
            if textView == yourTextView {
                let newHeight = yourCustomCell.frame.size.height + textView.contentSize.height
                yourCustomCell.frame.size.height = newHeight
                updateTableViewContentOffsetForTextView()
            }
        }
        // Animate cell, the cell frame will follow textView content
        func updateTableViewContentOffsetForTextView() {
            let currentOffset = tableView.contentOffset
            UIView.setAnimationsEnabled(false)
            tableView.beginUpdates()
            tableView.endUpdates()
            UIView.setAnimationsEnabled(true)
            tableView.setContentOffset(currentOffset, animated: false)
        }
    
    
        // UITableViewDelegate, UITableViewDataSource
        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return UITableViewAutomaticDimension
        }
    
    
    
        override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return UITableViewAutomaticDimension
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = yourCustomCell
            cell.selectionStyle = .none
            return cell
        }
    }
    

    The result is here: Before the code

    Result after using textViewDelegate, and custom resizing function After the code