Несоответствие заголовка UICollectionViewCompositionalLayout

Я создал собственный макет на основе UICollectionViewCompositionalLayout который представляет элементы каждого раздела на панели или карточке...

... здесь синяя область - это NSCollectionLayoutDecorationItem который передается в раздел через его decorationItemsсвойство. Этот фоновый элемент имеет свои собственные вставки содержимого, которые вставляют его из границ представления коллекции (серая область), а в разделе есть свои собственные вставки содержимого для вставки его в панель. Фиолетовая секция - это 3 элемента (ячейки) полной ширины.

Все работает так, как ожидалось.

Однако, когда я пытаюсь добавить заголовок в каждый раздел, используя boundarySupplementaryItems, заголовок (красный), кажется, игнорирует вставки содержимого раздела, но сам раздел изменяет размер, как если бы он был правильно расположен...

... заголовок прикрепляется к верхней части раздела, но высота раздела увеличивается на высоту заголовка + вставок.

Вот код, который я использую для создания макета...

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)

let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])

let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44.0))
let headerItem = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: "header", alignment: .top)

let panelBackgroundItem = NSCollectionLayoutDecorationItem.background(elementKind: "PanelBackground")
panelBackgroundItem.contentInsets = NSDirectionalEdgeInsets(top: 4.0, leading: 8.0, bottom: 4.0, trailing: 8.0)

let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [headerItem]
section.contentInsets = NSDirectionalEdgeInsets(top: 11.0, leading: 15.0, bottom: 11.0, trailing: 15.0)
section.decorationItems = [panelBackgroundItem]

let configuration = UICollectionViewCompositionalLayoutConfiguration()
configuration.interSectionSpacing = 4.0

let layout = UICollectionViewCompositionalLayout(section: section, configuration: configuration)
layout.register(PanelBackgroundView.self, forDecorationViewOfKind: "PanelBackground")

Может ли кто-нибудь посоветовать, как я могу заставить заголовок правильно позиционироваться - чуть выше первого элемента в разделе и с учетом установленных вставок содержимого?

2 ответа

@Rafael, я публикую ответ здесь, потому что в комментарии недостаточно символов. Это взято из расширенного макета collectionView WWDC 2019:

      func createLayout() -> UICollectionViewLayout {
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    
    let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(44))
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
    
    let section = NSCollectionLayoutSection(group: group)

    
    let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44)), elementKind: SectionHeadersFootersViewController.sectionHeaderElementKind, alignment: .top)
    header.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 0, bottom: 20, trailing: 0)
    let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44)), elementKind: SectionHeadersFootersViewController.sectionFooterElementKind, alignment: .bottom)
    section.boundarySupplementaryItems = [header,footer]
    section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)


    let config = UICollectionViewCompositionalLayoutConfiguration()
    config.interSectionSpacing = 10
    
    let layout = UICollectionViewCompositionalLayout(section: section, configuration: config)
    return layout
}

Результат

Один из способов обойти это — установить для contentInset.top нулевое значение и использовать UICollectionViewCompositionalLayoutConfiguration.interSectionSpacing. Тогда sectionHeader будет прямо над первой ячейкой, и мы также сможем настроить расстояние между разделами.

расстояние между разделами с использованием конфигурации

Другие вопросы по тегам