Reputation: 31323
Note: Similar questions have been asked on this topic but for some reason, the solutions mentioned in them doesn't seem to work for me so I'm posting this.
I have a UIScrollView
that fills the entire view of a view controller and a vertical UIStackView
embedded inside it.
class ViewController: UIViewController {
private let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.showsVerticalScrollIndicator = false
return scrollView
}()
lazy private var cardsStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 8
stackView.distribution = .fill
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .secondarySystemBackground
view.addSubview(scrollView)
scrollView.addSubview(cardsStackView)
let padding: CGFloat = 10
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: padding),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -padding),
cardsStackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
cardsStackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
cardsStackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
cardsStackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
cardsStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
])
addCardViews()
}
}
I want to add a number of UIView
subclasses (CardView
) to this stack view. These CardView
s only contain two UILabels
and this view is made to resize to fit the content of these labels.
class CardView: UIView {
lazy private var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 15, weight: .semibold)
return label
}()
lazy private var detailLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.numberOfLines = 0
return label
}()
init(title: String, details: String) {
super.init(frame: .zero)
titleLabel.text = title
detailLabel.text = details
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
backgroundColor = .systemGreen
layoutViews()
}
private func layoutViews() {
translatesAutoresizingMaskIntoConstraints = false
addSubview(titleLabel)
addSubview(detailLabel)
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
titleLabel.topAnchor.constraint(equalTo: topAnchor),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
detailLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
detailLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6),
detailLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
])
}
}
When I add these card views to the stack view, they don't seem to lay out one after the other.
It seems like the view is not taking the intrinsic content size of the labels when calculating the height of the view.
Any idea how to resolve this?
Upvotes: 1
Views: 1463
Reputation: 2217
In your CardView
you miss the detailLabel
bottom anchor:
private func layoutViews() {
translatesAutoresizingMaskIntoConstraints = false
addSubview(titleLabel)
addSubview(detailLabel)
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
titleLabel.topAnchor.constraint(equalTo: topAnchor),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
detailLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
detailLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 6),
detailLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
// This is missing
detailLabel.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
Upvotes: 2