swiftuitableviewuikittableviewuitableviewautomaticdimension

UIView-Encapsulated-Layout-Height constraint issue in Table View


class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // https://stackoverflow.com/a/27148268/14016301
        
        tableView.estimatedRowHeight = 2.0
        tableView.rowHeight = UITableView.automaticDimension
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        
        cell.textLabel?.text = "AAAA"
        let h = cell.contentView.heightAnchor.constraint(equalToConstant: 30)
        h.isActive = true
        
        _ = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { _ in
            UIView.animate(withDuration: 0.5) {
                h.constant = 500
                cell.layoutIfNeeded() // Layout issue here
            }
        })
        
        return cell
    }

}

I would like to know why this code generates a layout issue:

2021-02-18 20:59:18.679060+0200 nvrGonnaGivYouApp[23688:813946] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600003c79400 UITableViewCellContentView:0x7fae0520c060.height == 500   (active)>",
    "<NSLayoutConstraint:0x600003c78f50 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7fae0520c060.height == 30.3333   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600003c79400 UITableViewCellContentView:0x7fae0520c060.height == 500   (active)>

I tried looking at solutions here. But it didn't helped (as you can see I added the solution from here.

What I want to achieve is a 100% automatic height cell.

Thank you


Solution

  • Not sure why the issue is happening, but

    tableView.beginUpdates()
    tableView.endUpdates()
    

    fixed it somehow.

    Full code

    class ViewController: UITableViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // https://stackoverflow.com/a/27148268/14016301
            
            tableView.estimatedRowHeight = 2.0
            tableView.rowHeight = UITableView.automaticDimension
        }
        
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
            
            cell.textLabel?.text = "AAAA"
            let h = cell.contentView.heightAnchor.constraint(equalToConstant: 30)
            h.priority = .defaultHigh
            h.isActive = true
            
            _ = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { _ in
                h.constant = 500
                self.tableView.beginUpdates()
                self.tableView.endUpdates()
            })
            
            return cell
        }
    
    }