So I have a collection view inside a stackView, along with two UIViews, and the stackView is a subview of a scrollView. I want my collectionView to adjust its height dynamically and to not affect the other views in the stack view. I made a diagram showing what I am trying to achieve, so far... no success, the other two views keep getting stretched out or the collectionView doesn't seem to be exactly in the middle. Is there anyone that can help me? Please.
Constraints Code:
private func setupView() {
view.addSubview(scrollView)
scrollView.addSubview(mainStack)
headerStackView.addArrangedSubview(titleLabel)
footerStackView.addArrangedSubview(footerLabel)
mainStack.addArrangedSubview(headerStackView)
mainStack.addArrangedSubview(collectionView)
mainStack.addArrangedSubview(footerStackView)
let layoutGuide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
collectionView.heightAnchor.constraint(equalToConstant: 500),
scrollView.topAnchor.constraint(equalTo: layoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor, constant: 16),
scrollView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor, constant: -16),
mainStack.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
mainStack.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16),
mainStack.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
mainStack.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
mainStack.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor)
])
}
Collection View and StackView Code:
private lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.backgroundColor = .white
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: CustomCell.reuseId)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.isScrollEnabled = false
return collectionView
}()
private lazy var mainStack: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 16
stackView.distribution = .fill
return stackView
}()
Delegate Function:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let collectionViewSize = collectionView.frame.size.width - 16
let collectionViewHeightSize = collectionView.frame.size.height
return CGSize(width: collectionViewSize/2, height: collectionViewHeightSize / 2)
}
Here is my diagram:
This line is wrong:
mainStack.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor)
that says "keep the mainStack bottom at the view's bottom, regardless of scrolling.
it should be:
mainStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
now the mainStack
becomes the "scrollable content" of your scroll view.