Custom TableViewCell fires NSLayoutConstraint 'UIView-Encapsulated-Layout-Height' error

I use auto height for cells. And every time I want to update my cell with new data (there will be a model variable here), I updated my autodetection restrictions, and I get an error message. Here, to show the problem, I do not even change the restrictions. I just ask you to recount the layout.

When you initialize the cell for the first time: no warnings, no problems.

Error:

<NSLayoutConstraint:0x174285d70 'UIView-Encapsulated-Layout-Height'
 UITableViewCellContentView:0x1030f8a50.height == 500   (active)>

The code:

tableView.rowHeight = UITableViewAutomaticDimension

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

class TestTableViewCell: UITableViewCell {

  var model: X? {
    didSet {
      setNeedsLayout()
      layoutIfNeeded()
    }
  }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    let viewtop = UIView()
    let viewbottom = UIView()

    viewtop.backgroundColor = UIColor.yellow
    viewbottom.backgroundColor = UIColor.red
    contentView.backgroundColor = UIColor.blue

    contentView.addSubview(viewtop)
    contentView.addSubview(viewbottom)

    viewtop.snp.makeConstraints { (make) in
      make.top.equalTo(contentView)
      make.left.right.equalTo(contentView)
      make.height.equalTo(50)
    }

    viewbottom.snp.makeConstraints { (make) in
      make.top.equalTo(viewtop.snp.bottom)
      make.left.right.equalTo(contentView)
      make.bottom.equalTo(contentView)
      make.height.equalTo(120)
    }
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

}

Question: Why do I get an error message after requesting a re-assembly with the same restrictions?

EDIT: Another example for a better understanding here.

var botViewHeightConstraint:Constraint!
class TestTableViewCell: UITableViewCell {

  var model: Int? {
    didSet {
      if model == 1 {
        botViewHeightConstraint.update(offset:200)
      }else{
        botViewHeightConstraint.update(offset:120)
      }
    }
  }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    let viewtop = UIView()
    let viewbottom = UIView()

    viewtop.backgroundColor = UIColor.yellow
    viewbottom.backgroundColor = UIColor.red
    contentView.backgroundColor = UIColor.blue

    contentView.addSubview(viewtop)
    contentView.addSubview(viewbottom)

    viewtop.snp.makeConstraints { (make) in
      make.top.equalTo(contentView)
      make.left.right.equalTo(contentView)
      make.height.equalTo(50)
    }

    viewbottom.snp.makeConstraints { (make) in
      make.top.equalTo(viewtop.snp.bottom)
      make.left.right.equalTo(contentView)
      make.bottom.equalTo(contentView)
      botViewHeightConstraint = make.height.equalTo(120).constraint
    }
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

}

CellForRow Code:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let post = fetchedResultsController?.fetchedObjects?[(indexPath as NSIndexPath).section]  {
       let cell = tableView.dequeueReusableCell(withIdentifier: imagePostCellId) as! TestTableViewCell!
       cell.model = 1
       return cell
    }
}
+4
2

-, translatesAutoresizingMaskIntoConstraints false. . (, snapkit , .)

- - - , , - , . , . , , . , , . , , .

, , , UILabel, . .

(UIView-Encapsulated-Layout-Height ); ( systemLayoutSizeFitting(UILayoutFittingCompressedSize) , ).

intrinsicContentSize, invalidateIntrinsicContentSize, , - .

:

class MyView : UIView {
    var h : CGFloat = 200 {
        didSet {
            self.invalidateIntrinsicContentSize()
        }
    }
    override var intrinsicContentSize: CGSize {
        return CGSize(width:300, height:self.h)
    }
}

, h cellForRow .

, , v, MyView. :

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyCell
    let even = indexPath.row % 2 == 0
    cell.v.backgroundColor = even ? .red : .green
    cell.v.h = even ? 40 : 80 // triggers layout!
    return cell
}
+3

"make.height.equalTo(120)",

, 50 + 120.

, heightForRow UITableViewAutomaticDimension.

+2

Source: https://habr.com/ru/post/1655586/


All Articles