简体   繁体   English

Snapkit LayoutConstraints 无法同时满足约束

[英]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 .结果,我们得到了 thisthis

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM