使用Autolayout的可扩展UITableView单元导致UIViewAlertForUnsatisfiableConstraints

我正在尝试使用UITableViewAutomaticDimension行高和单元格的Autolayout组合制作可扩展单元格。 为了简单起见,我开始使用以下简单的代码,我期望它能够工作:

 import UIKit class ViewController: UITableViewController { let cells = [Cell(), Cell(), Cell()] override func viewDidLoad() { super.viewDidLoad() tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 50 for cell in cells { cell.tableView = tableView } } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 3 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return cells[indexPath.row] } } class Cell: UITableViewCell { var cons: NSLayoutConstraint? var tableView: UITableView? init() { super.init(style: .default, reuseIdentifier: nil) let button = UIButton() contentView.addSubview(button) button.addTarget(self, action: #selector(Cell.tapped(_:)), for: .touchUpInside) button.setTitle("Press me", for: .normal) button.setTitleColor(.red, for: .normal) button.translatesAutoresizingMaskIntoConstraints = false // constraining the button to the view, so that buttons height would define cell height let constraints = [ button.topAnchor.constraint(equalTo: contentView.topAnchor), button.rightAnchor.constraint(equalTo: contentView.rightAnchor), button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), button.leftAnchor.constraint(equalTo: contentView.leftAnchor), ] NSLayoutConstraint.activate(constraints) cons = button.heightAnchor.constraint(equalToConstant: 100) cons?.isActive = true } func tapped(_ sender: UIButton) { // change the height of the button, thus of the contentView too (since the button is constrained to the contentView) if cons?.constant == 100 { cons?.constant = 200 } else { cons?.constant = 100 } // tell the tableView to redraw itself to apply the change tableView?.beginUpdates() tableView?.setNeedsDisplay() tableView?.endUpdates() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

现在这似乎工作,但是,我仍然通过以下消息获取UIViewAlertForUnsatisfiableConstraints警告:

 ( "", "", "", "" ) Will attempt to recover by breaking constraint  

似乎估计的(或当前的)行高度与我提供的自动布局约束相冲突。 仍然,使用以下代码刷新tableView将按预期显示它:

 tableView?.beginUpdates() tableView?.setNeedsDisplay() tableView?.endUpdates() 

如何删除警告?

我知道简单地将高度约束的优先级更改为999将删除警告,但在我看来,作为一个黑客来删除它,而不是作为解决方案。 如果我弄错了,请解释一下。 谢谢。

将高度约束优先级设置为999可能感觉像是一个黑客,但根据Apple的文档:

注意不要觉得有义务使用所有1000个优先级值。 事实上,优先级应围绕系统定义的低(250),中(500),高(750)和所需(1000)优先级进行一般集群。 您可能需要制作比这些值高一点或两点的约束,以帮助防止关联。 如果你要超越它,你可能想要重新检查你的布局逻辑。

可能有点不直观:

“我希望按钮高度控制单元格高度,因此降低其优先级????”

但是,这似乎是“正确”的做法。

参考: https : //developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html#//apple_ref/doc/uid/TP40010853-CH9-SW19

删除高度约束,即200,因为它与顶部和底部约束冲突。

希望能帮助到你..