如何正确地在具有内在内容大小的视图之间进行约束?

How correctly make constraints between view with intrinsic content size?

我在UIView中有两个UILabel(垂直方向),在一个"row"中有UIButton。我需要得到这个结果:

查看初始化代码:

private lazy var contentView: UIView = {
    let view = UIView(frame: .zero)
    view.translatesAutoresizingMaskIntoConstraints = false

    return view
  }()

  private lazy var priceView: UIView = {
    let view = UIView(frame: .zero)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.setContentHuggingPriority(.required, for: .horizontal)

    return view
  }()

  private lazy var priceLabel: UILabel = {
    let label = UILabel(frame: .zero)
    label.numberOfLines = 1
    label.translatesAutoresizingMaskIntoConstraints = false

    return label
  }()

  private lazy var oldPriceLabel: UILabel = {
    let label = UILabel(frame: .zero)
    label.numberOfLines = 1
    label.translatesAutoresizingMaskIntoConstraints = false

    return label
  }()

  private lazy var callButton: UIButton = {
    let button = UIButton(frame: .zero)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.layer.cornerRadius = 22.0
    button.setTitleColor(.white, for: .normal)
    button.setTitle("Call", for: .normal)
    button.setContentHuggingPriority(.defaultLow, for: .horizontal)
    button.setContentCompressionResistancePriority(.required, for: .horizontal)

    return button
  }()

我使用 SnapKit 进行约束:

self.contentView.snp.makeConstraints { make in
  make.top.bottom.equalToSuperview()
  make.left.equalToSuperview().offset(16.0)
  make.right.equalToSuperview().offset(-16.0)
}
  self.priceView.snp.makeConstraints { make in
    make.centerY.left.equalToSuperview()
    make.right.equalTo(self.callButton.snp.left)

  }
  self.priceLabel.snp.makeConstraints { make in
    make.left.equalToSuperview()
    make.top.equalToSuperview()
    make.right.lessThanOrEqualToSuperview()
  }

  self.oldPriceLabel.snp.makeConstraints { make in
    make.left.bottom.equalToSuperview()
    make.top.equalTo(self.priceLabel.snp.bottom).offset(8.0)
    make.right.lessThanOrEqualToSuperview()
  })
  self.callButton.snp.makeConstraints { make in
   make.left.equalTo(self.priceView.snp.right)
    make.centerY.equalToSuperview()
    make.height.equalTo(44.0)
    make.right.equalToSuperview()

  }

我希望 priceView 缩小到 UILabel 的大小并 callButton 拉伸所有空闲 space。拥抱和压缩不起作用,我不明白为什么。

现在:

首先,您不必在每个视图中将 translateAutoresizingMaskIntoConstraints 设置为 false,因为您正在使用 SnapKit.

接下来,最好的处理方式就是利用UIStackView的目的。

就这么简单:

self.view.addSubview(self.stackView_Main)
self.stackView_Main.snp.makeConstraints { (make) in
    make.height.equalTo(44.0)
    make.leading.trailing.equalToSuperview().inset(16.0)
    make.top.equalToSuperview().inset(100.0)
}

self.callButton.snp.makeConstraints { (make) in
    make.top.bottom.equalToSuperview()
}

你会得到完美的,没有警告:

完整示例代码:

import SnapKit
import UIKit

class ViewController: UIViewController {

    private lazy var stackView_Main: UIStackView = {
        let stackView = UIStackView(arrangedSubviews: [self.stackView_Price, self.callButton])
        stackView.axis = .horizontal
        stackView.spacing = 5.0
        stackView.alignment = .leading
        stackView.distribution = .fill
        return stackView
    }()

    private lazy var stackView_Price: UIStackView = {
        let stackView = UIStackView(arrangedSubviews: [self.priceLabel, self.oldPriceLabel])
        stackView.axis = .vertical
        stackView.spacing = 5.0
        return stackView
    }()

    private lazy var priceLabel: UILabel = {
        let label = UILabel(frame: .zero)
        label.numberOfLines = 1
        label.text = "500 000 000"
        return label
    }()

    private lazy var oldPriceLabel: UILabel = {
        let label = UILabel(frame: .zero)
        label.numberOfLines = 1
        label.text = "999 999 999 999"
        return label
    }()

    private lazy var callButton: UIButton = {
        let button = UIButton(frame: .zero)
        button.layer.cornerRadius = 22.0
        button.backgroundColor = .black
        button.setTitleColor(.white, for: .normal)
        button.setTitle("Call", for: .normal)
        button.setContentHuggingPriority(.defaultLow, for: .horizontal)
        button.setContentCompressionResistancePriority(.required, for: .horizontal)

        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()


        self.view.addSubview(self.stackView_Main)
        self.stackView_Main.snp.makeConstraints { (make) in
            make.height.equalTo(44.0)
            make.leading.trailing.equalToSuperview().inset(16.0)
            make.top.equalToSuperview().inset(100.0)
        }

        self.callButton.snp.makeConstraints { (make) in
            make.top.bottom.equalToSuperview()
        }
    }


}

如果有帮助请告诉我 ;)

如果您不想使用 UIStackView,您可以轻松解决问题...

对于每个标签,更改:

make.right.lessThanOrEqualToSuperview()

至:

make.right.equalToSuperview()

这应该可以解决问题。