UICollectionViewCompositionalLayout по горизонтали, не вычисляя ширину содержимого при использовании ориентировочной, а не по горизонтали

I want the cell to horizontaly Hug its content

Я использую UICollectionViewCompositionalLayout в горизонтальном режиме и с widthDimension: .estimated(100) который должен рассчитать размер содержимого

но ширина ячейки / группы НЕ рассчитывается по размеру содержимого и устанавливается на оценочные значения, поскольку это будет абсолютное значение

Даже добавление ограничения ширины к метке не влияет на размер ячеек.

Это ожидаемое поведение? Если да, то почему? и как получить желаемый результат?

class LabelCell: UICollectionViewCell {
    @IBOutlet weak var label: UILabel!
}

class ViewController: UIViewController, UICollectionViewDataSource {

    func buildLayout() -> UICollectionViewCompositionalLayout {

        let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(100), heightDimension: .absolute(32))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)

        let groupSize = NSCollectionLayoutSize(widthDimension: .estimated(100), heightDimension: .absolute(32))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1)

        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = 10

        let configuration = UICollectionViewCompositionalLayoutConfiguration()
        configuration.scrollDirection = .horizontal
        return UICollectionViewCompositionalLayout(section: section, configuration: configuration)

    }

    @IBOutlet weak var collectionView: UICollectionView!

    let items = ["1", "12", "12345", "123456789"]

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.collectionViewLayout = buildLayout()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let c = collectionView.dequeueReusableCell(withReuseIdentifier: "LabelCell", for: indexPath) as! LabelCell
        c.label.text = items[indexPath.row]
        return c
    }
}

1 ответ

Решение

Чтобы правильно определить размер ячеек, измените:

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

К этому:

let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])

Я не уверен, почему это изменение необходимо, поскольку эти строки говорят об одном и том же. Тем не менее, он будет работать, если в вашей ячейке представления коллекции указан фактический размер ячейки, переопределивsizeThatFits(_:), preferredLayoutAttributesFitting(_:), используя Auto Layout и т. д.

В документации для первой сигнатуры функции сказано:

Задает группу, в которой будет N элементов одинакового размера по горизонтальной оси.

Комментарий для второй сигнатуры функции не делает таких заявлений относительно элементов одинакового размера. Он говорит:

Задает группу, которая будет повторять элементы до тех пор, пока не будет исчерпано доступное горизонтальное пространство.