I currently have a couple of collection views that use compositional layouts that I'm trying to add to two separate vertical stack views on top of each other. One of my collection view will be going into the headerContentView and the other will be going into the actual contentView.
My collectionView should be self-sizing by invalidating the intrinsic content size. However, for some reason, only one of the collectionView is visible because one will size itself to the content size. However, the other will have a height of 0. As a note, the stack view that contains the second collectionView also has a height of zero.
I need help to have the collection views size properly. Thanks for your time.
StackViews:
internal let contentStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
return stackView
}()
Constraints on StackView:
private func setUpView() {
backgroundColor = .blue
layoutMargins = UIEdgeInsets(top: 0, left: 16, bottom: 24, right: 16)
addSubview(headerView)
addSubview(contentStackView)
// Preserve superview layout margins so that sub-elements can be laid out using layoutMarginsGuide
contentStackView.preservesSuperviewLayoutMargins = true
[headerView, contentStackView].forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
NSLayoutConstraint.activate([
headerView.topAnchor.constraint(equalTo: topAnchor),
contentStackView.topAnchor.constraint(equalTo: headerView.bottomAnchor, constant: 16),
layoutMarginsGuide.bottomAnchor.constraint(lessThanOrEqualTo: contentStackView.bottomAnchor),
headerView.leadingAnchor.constraint(equalTo: leadingAnchor),
headerView.trailingAnchor.constraint(equalTo: trailingAnchor),
contentStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
contentStackView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
private func setUpHeaderView() {
// Preserve superview layout margins so that sub-elements can be laid out using layoutMarginsGuide
headerView.preservesSuperviewLayoutMargins = true
headerContentStackView.preservesSuperviewLayoutMargins = true
headerView.addSubview(headerContentStackView)
headerContentStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
headerContentStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
headerView.bottomAnchor.constraint(lessThanOrEqualTo: headerContentStackView.bottomAnchor),
headerContentStackView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor),
headerContentStackView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor)
])
// Add header contents to header content stack view
headerContentStackView.addArrangedSubview(headerBarView)
headerContentStackView.addArrangedSubview(notificationView)
}
Compostional layout:
private static func generateCompositionalLayout() -> UICollectionViewLayout {
// Items
let itemSize: NSCollectionLayoutSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fractionalWidthForItems),
heightDimension: .fractionalHeight(UIConstantsIconTileCollectionView.PhaseTwo.fullWidthOrHeight)
)
let fullItem: NSCollectionLayoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
// Groups
let groupSize: NSCollectionLayoutSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fullWidthOrHeight),
heightDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fractionalWidthForGroups)
)
let group: NSCollectionLayoutGroup = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitem: fullItem,
count: UIConstantsIconTileCollectionView.PhaseTwo.numberOfItemsPerGroup
)
group.interItemSpacing = .fixed(UIConstantsIconTileCollectionView.PhaseTwo.interGroupSpacing)
// Section
let section: NSCollectionLayoutSection = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(
top: 0,
leading: UIConstantsIconTileCollectionView.PhaseTwo.interSectionSpacing,
bottom: 0,
trailing: UIConstantsIconTileCollectionView.PhaseTwo.interSectionSpacing
)
return UICollectionViewCompositionalLayout(section: section)
}
Self Sizing Collection View:
// MARK: - View Layout
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return contentSize
}