UITableView自动标注不起作用:UIView封装布局高度错误



我正在尝试实现自调整表视图单元格大小。我在单元格内设置了自动布局高度,但它显示了自动布局错误。

我设置translatesAutoresizingMaskIntoConstraints=false,并设置UITableView.autoDimension.

它显示自动布局错误如下。

[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:0x6000024ce9e0 DisposeSecond.MyCell:0x7f9ba7104aa0'cell'.height == 100   (active)>",
"<NSLayoutConstraint:0x6000024ce800 'UIView-Encapsulated-Layout-Height' DisposeSecond.MyCell:0x7f9ba7104aa0'cell'.height == 100.333   (active)>"
)


我的实现非常简单。


import UIKit
class MyCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
translatesAutoresizingMaskIntoConstraints = false
self.heightAnchor.constraint(equalToConstant: 100).isActive = true
// Set debug colors to visualize heigh
layer.borderWidth = 2
layer.borderColor = UIColor.blue.cgColor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(MyCell.self, forCellReuseIdentifier: "cell")
}

// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 30
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyCell
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// I know it is set automatically but just indeed
return UITableView.automaticDimension
}
}

第一个问题:作为一般规则,您永远不应该用以下内容修改单元格视图本身:

translatesAutoresizingMaskIntoConstraints = false
self.heightAnchor.constraint(equalToConstant: 100).isActive = true

相反,修改单元格内容:

contentView.heightAnchor.constraint(equalToConstant: 100.0).isActive = true

接下来,当使用自动调整单元格和表视图(或集合视图(的大小时,自动布局在进行多次传递时经常会遇到冲突。这是由于分隔符、对象封装尺寸等因素造成的。

您可以通过在约束上使用999priority而不是默认的1000:来避免这种情况

// create heightAnchor for contentView
let c = contentView.heightAnchor.constraint(equalToConstant: 100.0)
// set priority to 999 to avoid auto-layout conflicts with auto-sizing cells
c.priority = UILayoutPriority(rawValue: 999)
// activate it
c.isActive = true

第三,在使用自动布局和自动调整单元格大小时,几乎不需要实现heightForRowAt。除非您知道特别为什么需要实现它,否则不要。

这是你的手机类,用上面的注释修改:

class MyCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// never modify self in this way
//translatesAutoresizingMaskIntoConstraints = false
//self.heightAnchor.constraint(equalToConstant: 100).isActive = true
// create heightAnchor for contentView
let c = contentView.heightAnchor.constraint(equalToConstant: 100.0)
// set priority to 999 to avoid auto-layout conflicts with auto-sizing cells
c.priority = UILayoutPriority(rawValue: 999)
// activate it
c.isActive = true
// Set debug colors to visualize heigh
layer.borderWidth = 2
layer.borderColor = UIColor.blue.cgColor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}