[英]Snapkit LayoutConstraints Unable to simultaneously satisfy constraints
I have simple UITableView and custom UITablViewCell in my project, which created programmatically and use SnapKit for auto layout its.我的项目中有简单的 UITableView 和自定义 UITablViewCell,它们以编程方式创建并使用 SnapKit 进行自动布局。 When I run app, everything work fine and get some LayoutConstraints error in log.
当我运行应用程序时,一切正常,并在日志中出现一些 LayoutConstraints 错误。
UITableViewCell UITableViewCell
import UIKit
import SnapKit
class TestTableViewCell: UITableViewCell {
...
private lazy var containerView: UIView = {
let view = UIView()
return view
}()
private lazy var centerStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [titleLabel, disclosureImageView])
stackView.axis = .horizontal
stackView.distribution = .fill
stackView.spacing = 5.0
return stackView
}()
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
return label
}()
private lazy var disclosureImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
imageView.image = UIImage(named: "disclosure")
return imageView
}()
..
private func setupUI() {
selectionStyle = .none
backgroundColor = .background
contentView.addSubview(containerView)
containerView.backgroundColor = .white
containerView.layer.cornerRadius = 12
containerView.clipsToBounds = true
containerView.addSubview(centerStackView)
setNeedsUpdateConstraints()
}
// MARK: - Update Constraints
override func updateConstraints() {
containerView.snp.updateConstraints { make in
make.top.bottom.equalToSuperview().inset(8)
make.leading.trailing.equalToSuperview().inset(16)
make.height.equalTo(100)
}
centerStackView.snp.updateConstraints { make in
make.center.equalToSuperview()
}
super.updateConstraints()
}
}
How I can fix this constraint error ?我该如何解决这个约束错误?
There are actually two conflicts for each table view cell.每个表格视图单元格实际上存在两个冲突。 You can copy-paste the sets of constraints are in conflict into https://www.wtfautolayout.com and see exactly why they are conflicting.
您可以将有冲突的约束集复制粘贴到https://www.wtfautolayout.com中,并查看它们发生冲突的确切原因。 As a result, we get this and this .
结果,我们得到了 this和this 。
We can see that the first conflict is caused by your container view having a height constraint, but the table view itself also adds a height constraint to the cell to enforce its cells' sizes,我们可以看到第一个冲突是由您的容器视图具有高度约束引起的,但是表格视图本身也为单元格添加了高度约束以强制其单元格的大小,
"<NSLayoutConstraint:0x7b1400031920 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7b4c00003640.height == 116.5 (active)>"
For some reason, the constant here is 116.5, not 116 as you would expect from the 100 points of height of the container view + the 16 points of inset.出于某种原因,这里的常数是 116.5,而不是 116,正如您从容器视图的 100 点高度 + 16 点插图中所期望的那样。
You can either change it to您可以将其更改为
make.height.greaterThanOrEqualTo(100)
Or remove the height constraint completely:或者完全删除高度约束:
// make.height.equalTo(100)
and use the delegate method heightForRowAt
to control the cell height instead:并使用委托方法
heightForRowAt
来控制单元格高度:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
116
}
As for the second conflict, it is caused by a constraint constraining the stack view's width to 0, being in conflict with the fact that there must be some spacing between the image and label.至于第二个冲突,它是由将堆栈视图的宽度限制为0的约束引起的,与图像和标签之间必须有一些间距的事实相冲突。
"<NSLayoutConstraint:0x7b1400031b50 'UIView-Encapsulated-Layout-Width' UIStackView:0x7b4c000039c0.width == 0 (active)>"
If you move the following code from updateConstraints
into setupUI
, the conflict is resolved:如果将以下代码从
updateConstraints
移到setupUI
中,则冲突已解决:
containerView.snp.updateConstraints { make in
make.top.bottom.equalToSuperview().inset(8)
make.leading.trailing.equalToSuperview().inset(16)
make.height.greaterThanOrEqualTo(100)
}
centerStackView.snp.updateConstraints { make in
make.center.equalToSuperview()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.