5

I have this basic compositional layout for a view of tags. The cells contain just a label with auto layout constraints. The goal is to auto size the cells both vertically and horizontally to fit the label. With compositional layout I can only get an estimated width or height when I set NSCollectionLayoutGroup to vertical or horizontal respectively. I can't get it to work for both axis. Anything I'm missing? This is what it should look like:

enter image description here

let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

        let layoutSize = NSCollectionLayoutSize(widthDimension: .estimated(100), heightDimension: .estimated(40))

        let item = NSCollectionLayoutItem(layoutSize: layoutSize)

        let group = NSCollectionLayoutGroup.vertical(layoutSize: layoutSize, subitem: item, count: 1)

        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20)
        section.interGroupSpacing = 10
        section.orthogonalScrollingBehavior = .groupPaging

        return section
    }
Nico Reese
  • 261
  • 6
  • 14

2 Answers2

9

Not sure if I understand your question correctly, but here is how you a achieve the following tag view.

Multiline Tag View

  private func createLayout() -> UICollectionViewLayout {

        let estimatedHeight: CGFloat = 50
        let estimatedWidth: CGFloat = 100

        let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(estimatedWidth),
                                              heightDimension: .estimated(estimatedHeight))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)

        item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil, top: .fixed(4), trailing: .fixed(8), bottom: .fixed(4))

        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(estimatedHeight))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                       subitems: [item])

        let section = NSCollectionLayoutSection(group: group)

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }
ThorbenA
  • 1,863
  • 3
  • 16
  • 27
  • Could you tell me plz, why this works only with labels, but when I put label in UIView - this doesn't work? Or when I add icon before label - I see only empty cells, but not my icon and label – Gleb Dec 22 '22 at 05:23
0

add label to the contentView of UICollectionViewCell (not directly to the cell) ..... and add constraints on both sides

class SomeCell: UICollectionViewCell { 

private lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false 
    label.textAlignment = .center  
    return label
}()

override init(frame: CGRect) {
    super.init(frame: frame) 
    contentView.addSubview(titleLabel) //<<----------
    setupConstraints()
}
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

private func setupConstraints(){
    NSLayoutConstraint.activate([
        titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
        titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
        titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
    ])
} 

}