在编程中,使用标签放在容器视图内的时候有几种情况。
如果标签是容器的唯一子视图,你只需要将其约束到容器的边界上,并将标签的
contentCompressionResistancePriority
和
contentHuggingPriority
都设置为
required
。如果这样做了,就不需要指定高度;高度将随着标签的增长而增长。
class LabelContainerView: UIView {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
commonSetup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonSetup()
}
func commonSetup() {
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.setContentHuggingPriority(.required, for: .vertical)
label.setContentCompressionResistancePriority(.required, for: .vertical)
label.text = "Hello, World."
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.topAnchor.constraint(equalTo: topAnchor),
label.trailingAnchor.constraint(equalTo: trailingAnchor),
label.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
}
如果你想在标签周围添加一些填充,你可以将其限制为父视图的layoutMarginsGuide
,并额外调整layoutMargins
以扩展/收缩填充。
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
])
然而,如果您在容器内有一个额外的视图(例如自定义背景视图),则需要告诉自动布局使用标签的intrinsicContentSize
。
@IBDesignable
class ContainerView: UIView {
let customBackgroundView = CustomBackgroundView()
let label = UILabel()
override var intrinsicContentSize: CGSize {
label.intrinsicContentSize
}
override init(frame: CGRect) {
super.init(frame: frame)
commonSetup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonSetup()
}
func commonSetup() {
addSubview(customBackgroundView)
addSubview(label)
customBackgroundView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
label.setContentHuggingPriority(.required, for: .vertical)
label.setContentCompressionResistancePriority(.required, for: .vertical)
label.text = "Hello, World."
NSLayoutConstraint.activate([
customBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor),
customBackgroundView.topAnchor.constraint(equalTo: topAnchor),
customBackgroundView.trailingAnchor.constraint(equalTo: trailingAnchor),
customBackgroundView.bottomAnchor.constraint(equalTo: bottomAnchor),
label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
])
}
}
class CustomBackgroundView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonSetup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonSetup()
}
func commonSetup() {
backgroundColor = .clear
}
override func draw(_ rect: CGRect) {
let path = UIBezierPath(rect: bounds)
UIColor.red.setStroke()
path.stroke()
}
}
很多时候,自动布局的歧义可以通过使用
intrinsicContentSize
来解决。这为布局引擎提供了必要的提示,以计算其内部视图的大小。
如果一个视图只有固有的高度而没有宽度(或反之亦然),则始终使用常量
UIView.noIntrinsicMetric
来表示未定义的维度。
override var intrinsicContentSize: CGSize {
.init(width: UIView.noIntrinsicMetric, height: 42)
}