Constraint bug with UITableViewAutomaticDimension

I am having a hard time with dynamic height custom tableView cells.

So I get the "Unable to simultaneously satisfy constraints." warning (but just sometimes, like 1 out of a thousand times)


I think that UITableViewAutomaticDimension gives the problem. In the example it expects 88.3333 height, but maybe it is incorrect. (But most of the time it works, I don't understand what is happening)

What am I doing wrong, could anyone help? Tried everything..

Code:

var cellHeights: [IndexPath : CGFloat] = [:]
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeights[indexPath] = cell.frame.size.height

        if indexPath.row == UserWorldMessagesStore.shared.worldMessages.count - 1 && userWorldMessagesCanLoadMore == true {
            loadOlderOwnWorldMessages()
        }
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if cellHeights[indexPath] != nil {
            return CGFloat(Float(cellHeights[indexPath] ?? 0.0))
        }
        else {
            return UITableViewAutomaticDimension
        }
    }

Warning:

2018-05-19 19:58:54.879876+0200 PipeTest[3378:1282243] [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:0x1c0297fc0 V:|-(10)-[UILabel:0x125d5db40'Heyy']   (active, names: '|':UIView:0x125d03400 )>",
    "<NSLayoutConstraint:0x1c0298010 V:[UILabel:0x125d5db40'Heyy']-(10)-|   (active, names: '|':UIView:0x125d03400 )>",
    "<NSLayoutConstraint:0x1c0298100 PipeTest.profilePictureImageView:0x125d56fc0.height == 22   (active)>",
    "<NSLayoutConstraint:0x1c0298240 UIView:0x125e58150.height == 27   (active)>",
    "<NSLayoutConstraint:0x1c0298600 PipeTest.profilePictureImageView:0x125d56fc0.top == UITableViewCellContentView:0x125d50850.topMargin   (active)>",
    "<NSLayoutConstraint:0x1c02986a0 V:[PipeTest.profilePictureImageView:0x125d56fc0]-(3)-[UIView:0x125d03400]   (active)>",
    "<NSLayoutConstraint:0x1c02988d0 UIView:0x125e58150.bottom == UITableViewCellContentView:0x125d50850.bottomMargin   (active)>",
    "<NSLayoutConstraint:0x1c0298970 V:[UIView:0x125d03400]-(7)-[UIView:0x125e58150]   (active)>",
    "<NSLayoutConstraint:0x1c0299230 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x125d50850.height == 88.3333   (active)>"
)

Upvotes: 1

Views: 393

Answers (1)

mag_zbc
mag_zbc

Reputation: 6982

Full warning text should include something like

Will attempt to recover by breaking constraint  
<NSLayoutConstraint:somePointer V:some constraint>

Lowering that constraint's priority to 999 should make this warning go away.

The reason for it is in that line:

<NSLayoutConstraint:0x1c0299230 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x125d50850.height == 88.3333   (active)>

This is a system provided constraint that tells the table view what the cell's height should be and it's value is based on what you return from estimatedHeightForRowAt. The warning is thrown before the proper cell size is calculated (in the end it will be calculated properly) so it's safe to just lower the priority of some other constraint, so the system-provided one takes precedence.

Upvotes: 4

Related Questions