我正在尝试使用UITableViewAutomaticDimension行高和单元格的自动布局来制作可扩展单元格。为了使事情变得简单,我从下面的简单代码开始,我希望它们能正常工作:
UITableViewAutomaticDimension
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以下消息警告:
UIViewAlertForUnsatisfiableConstraints
( "<NSLayoutConstraint:0x17408c7b0 V:|-(0)-[UIButton:0x109e10290'Press me'] (active, names: '|':UITableViewCellContentView:0x109e0fd90 )>", "<NSLayoutConstraint:0x17408c8a0 UIButton:0x109e10290'Press me'.bottom == UITableViewCellContentView:0x109e0fd90.bottom (active)>", "<NSLayoutConstraint:0x17408c990 UIButton:0x109e10290'Press me'.height == 200 (active)>", "<NSLayoutConstraint:0x17408db10 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x109e0fd90.height == 100 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x17408c990 UIButton:0x109e10290'Press me'.height == 200 (active)>
估计(或当前)行高似乎与我提供的自动布局约束相冲突。尽管如此,使用以下代码刷新tableView仍将按预期显示它:
tableView?.beginUpdates() tableView?.setNeedsDisplay() tableView?.endUpdates()
如何删除警告?
我知道将高度限制的优先级简单地更改为999即可删除警告,但在我看来,删除警告是一种hack,而不是解决方案。如果我弄错了,请解释。谢谢。
将高度限制优先级设置为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