1

I’m trying to get rid of constraint problems appearing in my UITableView with custom cells. The height of the rows is set to automatic, and is defined by constraints.

For example, I have a cell containing only a UITextField that has a height set (44.0) and that is sticking at top and bottom.

Custom cell

When the separators are deactivated on my UITableView, there is no problem. Therefore, when I activate them, I have the following warning in my console:

[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:0x28333a670 UITextField:0x103655390.height == 44   (active)>",
    "<NSLayoutConstraint:0x28333a7b0 V:[UITextField:0x103655390]-(0)-|   (active, names: '|':UITableViewCellContentView:0x103654e20 )>",
    "<NSLayoutConstraint:0x28333a990 V:|-(0)-[UITextField:0x103655390]   (active, names: '|':UITableViewCellContentView:0x103654e20 )>",
    "<NSLayoutConstraint:0x28333ba20 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x103654e20.height == 44.3333   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x28333a670 UITextField:0x103655390.height == 44   (active)>

It seems that the system adds the UIView-Encapsulated-Layout-Height constraint to set the height and it contains the size of the separator (0.33). It conflicts with the desired height, and it overrides my constraints.

This is a problem when I try to update the height of the cell by changing the height of the UITextField, for example.

Is there any way to remove those annoying warnings?

Edit

Thank to you I found a way to get rid of the warning and to get animated height transformations at runtime:

1: set the bottom constraint priority ≤ 999,

2: after constraint change, call

tableView.beginUpdates()
tableView.endUpdates()

This will recalculate the height of the row, and UITableView automatically animates the change.

BUT the animation is glitchy…

If you let the bottom constraint priority at 1000, the animation is smooth, but the warning appears every time the constraint changes.

If you set the bottom constraint priority at 999 for example, warnings are gone, but the content of the cell jumps from one position to another…

I will stay with the warnings for the moment, and hope that Apple fix this in the future versions.

Thank you for your answers!

Steve G.
  • 589
  • 5
  • 13
  • change the top and bottom constraints priority – Raju Abe Mar 13 '20 at 09:08
  • 2
    Does this answer your question? (Specifically, the answers saying to change the bottom constraint's priority to 999) [UITableView auto resizing row constraint breaking mysteriously on iPhone 6Plus](https://stackoverflow.com/questions/32172250/uitableview-auto-resizing-row-constraint-breaking-mysteriously-on-iphone-6plus) – TylerP Mar 13 '20 at 09:08
  • Those solutions remove the warnings, but it doesn’t seem good as it tells the system not to listen to my constraints. If I change the height of the `UITextField`, the cell does not change its height as my constraints are erased by the system-calculated one. – Steve G. Mar 13 '20 at 09:14
  • I just tested it (after changing the bottom constraint's priority to 999) – when I change the value of my text field's height constraint (to, say, 60), it does change the cell's height, and no warnings are produced. – TylerP Mar 13 '20 at 09:39
  • @TylerTheCompiler I’m sorry to hear that, I doesn’t work for me. When I dynamically update the constraint constant, the margin with the lowest priority is not taken in account, the row’s height doesn’t change and the component overflows at the bottom of the cell (its bottom margin is equal to `-height` pixels because the 0 constant value priority is lower than the system-set height) – Steve G. Mar 13 '20 at 09:54
  • Oh did you mean at runtime? I thought you just meant changing the height in the storyboard/xib. I just tried again, and when I changed the height constraint's constant at runtime, it indeed did not change the height of the cell - BUT I then tried calling `reloadData` on the tableView after changing the constraint's constant, and that _did_ update the cell to the correct height. – TylerP Mar 13 '20 at 10:06
  • Yes, sorry if I wasn’t clear enough. The `reloadData` works because the system recalculates the height of every row, but it will not allow to animate the change, for example. I tried with a call to `setLayout` when changing the height, and it doesn’t work either… – Steve G. Mar 13 '20 at 10:10

1 Answers1

-1

@blacKeuz Try like below on your CellForRowAtIndexPath on UITableViewDataSource

    let cell = tableView.dequeueReusableCell(withIdentifier: YourCustomTableViewCell.reuseIdentifier, for: indexPath) as! YourCustomTableViewCell

            cell.setNeedsUpdateConstraints()
            cell.updateConstraintsIfNeeded()


            cell.setNeedsLayout()
            cell.layoutIfNeeded()

            return cell
Ram
  • 764
  • 1
  • 7
  • 20
  • Nope, this does not remove the warnings. – Steve G. Mar 13 '20 at 09:16
  • @blacKeuz Actually you need to remove your static height value `44` which is on your textField. I hope then you will not see the warnings. – Ram Mar 13 '20 at 09:20
  • if I remove it, then how can I get an automatic calculated row height? It relies on constraint to calculate the height of the height (and it works without separators, actually). – Steve G. Mar 13 '20 at 09:22
  • @blacKeuz Seems you set constraints all sides like left, right, top and bottom too. You need to set UITableView.estimatedRowHeight = 44.0 and then UItableView.rowHeight = UITableViewAutomaticDimension. – Ram Mar 13 '20 at 09:25
  • @blacKeuz Otherwise you can set your UITextField height like `44` with greaterThanOrEqualToConstraint. Try with this. I hope it will work. – Ram Mar 13 '20 at 09:27
  • The `UITableView` is set correctly (automatic row height and estimated height at 44.0). I tried to set it in Interface Builder and also programmatically, the warnings stays with both implementations. – Steve G. Mar 13 '20 at 09:28
  • @blacKeuz have you seen my last comment and you can try with put inequation constraint for textField height. – Ram Mar 13 '20 at 09:31
  • The `greaterThanOrEqual` solution works, it removes the warnings! But it does not allow to tweak the height of the components to change the rows’ height because the constraints are not fixed anymore (and that is why I use constraints and not fixed heights for my rows). :( – Steve G. Mar 13 '20 at 09:35