使用Autolayout的可扩展UITableView单元导致UIViewAlertForUnsatisfiableConstraints [英] Expandable UITableView Cell using Autolayout results in UIViewAlertForUnsatisfiableConstraints
问题描述
我正在尝试使用 UITableViewAutomaticDimension
行高和Autolayout单元格的组合来制作可扩展单元格。为了简单起见,我开始使用以下简单的代码,我希望它可以工作:
I am trying to make expandable cells using combination of UITableViewAutomaticDimension
row height and Autolayout of the cells. To make things simple, I started with the following simple code, that I expected to work:
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
警告,并显示以下消息:
Now this seems to be working, however, I still do get UIViewAlertForUnsatisfiableConstraints
warning with the following message:
(
"<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将按预期显示:
It seems that the estimated (or current) row height collides with the autolayout constraint provided by me. Still, refreshing the tableView using following code will display it as expected:
tableView?.beginUpdates()
tableView?.setNeedsDisplay()
tableView?.endUpdates()
如何删除警告?
我知道简单地将高度约束的优先级更改为999将删除警告,但在我看来这是一个删除它的黑客,而不是作为解决方案。如果我弄错了,请解释一下。谢谢。
I am aware that simple changing the priority of the height constraint to 999 will remove the warning, but it seems to me as a hack to remove it, not as a solution. If I am mistaken, please explain. Thanks.
推荐答案
将高度约束优先级设置为999可能感觉就像黑客一样,但根据Apple的文档:
Setting the height constraint priority to 999 may feel like a hack, but according to Apple's docs:
注意不要觉得有义务使用所有1000个优先级值。事实上,优先级应围绕系统定义的低(250),中(500),高(750)和所需(1000)优先级进行一般集群。您可能需要制作比这些值高一点或两点的约束,以帮助防止关联。如果你要超越它,你可能想要重新检查你的布局的逻辑。
NOTE Don’t feel obligated to use all 1000 priority values. In fact, priorities should general cluster around the system-defined low (250), medium (500), high (750), and required (1000) priorities. You may need to make constraints that are one or two points higher or lower than these values, to help prevent ties. If you’re going much beyond that, you probably want to reexamine your layout’s logic.
可能比直觉要差一点:
我希望按钮高度控制单元格高度,所以 降低 优先级????
"I want the button height to control the cell height, so lower its priority????"
但是,这似乎是正确的做法。
But, that does appear to be the "correct" way to do it.
这篇关于使用Autolayout的可扩展UITableView单元导致UIViewAlertForUnsatisfiableConstraints的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!