I have a horizontal collection view that I embedded in vertical stack view, how can I make collection view’s height to fit its content. The code I have now:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: Cell.self), for: indexPath) as? Cell else { return UICollectionViewCell() }
return cell
}
var collectionView: UICollectionView!
private lazy var stack = {
let stack = UIStackView()
stack.preservesSuperviewLayoutMargins = true
stack.distribution = .fill
stack.alignment = .fill
stack.axis = .vertical
stack.spacing = 4
stack.translatesAutoresizingMaskIntoConstraints = false
return stack
}()
let contentView = UIView()
let label = {
let l = UILabel()
l.numberOfLines = 0
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Example 1"
return l
}()
override func viewDidLoad() {
let layout = UICollectionViewCompositionalLayout { index, _ in
switch index {
case 0:
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)))
item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 4, bottom: 0, trailing: 4)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.95), heightDimension: .fractionalHeight(1)), subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
return section
default:
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)))
let verticalGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .absolute(200), heightDimension: .absolute(200)), subitem: item, count: 2)
let section = NSCollectionLayoutSection(group: verticalGroup)
return section
}
}
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(Cell.self, forCellWithReuseIdentifier: String(describing: Cell.self))
stack.addArrangedSubview(collectionView)
contentView.addSubview(label)
stack.addArrangedSubview(contentView)
stack.backgroundColor = .red
collectionView.backgroundColor = .blue
collectionView.dataSource = self
collectionView.heightAnchor.constraint(greaterThanOrEqualToConstant: 1).isActive = true
view.addSubview(stack)
NSLayoutConstraint.activate([
stack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
stack.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stack.trailingAnchor.constraint(equalTo: view.trailingAnchor),
contentView.topAnchor.constraint(equalTo: label.topAnchor),
contentView.bottomAnchor.constraint(equalTo: label.bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: label.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: label.trailingAnchor)
])
}
}
class Cell: UICollectionViewCell {
let label = {
let l = UILabel()
l.numberOfLines = 0
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Example 2"
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(label)
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: contentView.topAnchor),
label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
])
}
}
I already tried to set compression resistance but it didn’t help. No matter what the height of a collection view remains 1, although there is clearly a space to expand.
New contributor
Not Bad is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.