iOS - липкие заголовки со вставкой содержимого - представление заголовка не прокручивается, как ячейка

Мы попытались свернуть UICollectionView как список по карте. Это не следует путать с нижним листом, который привязывается к точке (например, к нижней, средней и высокой). Свойство flowlayout представления коллекции имеет sectionHeadersPinToVisibleBounds включенное значение. Я приложил образец проекта для справки. Есть ли способ, которым представление заголовка может перемещаться в верхнюю часть представления коллекции при прокрутке пользователя?

Вот пример проекта

Существенные изменения нужны мне, чтобы войти в это состояние:

let layout = UICollectionViewFlowLayout()
layout.sectionHeadersPinToVisibleBounds = true
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0

let collectionView = UICollectionView(frame: .zero,
                                              collectionViewLayout: layout)


override func viewWillLayoutSubviews() {
  super.viewWillLayoutSubviews()

  collectionView.contentInset = UIEdgeInsets(top: drawerHeight, left: 0, bottom: 0, right: 0)
}

Вот скриншот того, что вы увидите: введите здесь описание изображения

Красный цвет — это вид заголовка, который закреплен. Нужен ли мне пользовательский макет для обновления его положения при прокрутке пользователем?


person Siddharthan Asokan    schedule 03.03.2019    source источник


Ответы (2)


Я написал собственный StickyHeaderLayout, вдохновленный этим публикацией. Вот исправление моей ошибки:

class StickyHeaderLayout: UICollectionViewFlowLayout {

    override init() {
        super.init()
        configureLayout()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureLayout()
    }

    private func configureLayout() {
        self.sectionFootersPinToVisibleBounds = true
        self.sectionHeadersPinToVisibleBounds = true
        minimumLineSpacing = 0
        minimumInteritemSpacing = 0
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }

        for attribute in attributes {
            adjustAttributesIfNeeded(attribute)
        }
        return attributes
    }

    override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        guard let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath) else { return nil }
        adjustAttributesIfNeeded(attributes)
        return attributes
    }

    func adjustAttributesIfNeeded(_ attributes: UICollectionViewLayoutAttributes) {
        switch attributes.representedElementKind {
        case UICollectionView.elementKindSectionHeader?:
            adjustHeaderAttributesIfNeeded(attributes)
        default:
            break
        }
    }

    private func adjustHeaderAttributesIfNeeded(_ attributes: UICollectionViewLayoutAttributes) {
        guard let collectionView = collectionView else { return }
        guard attributes.indexPath.section == 0 else { return }

        if collectionView.contentOffset.y <= 0 {
            attributes.frame.origin.y = 0
        } else {
            attributes.frame.origin.y = collectionView.contentOffset.y
        }
    }
}
person Siddharthan Asokan    schedule 03.03.2019
comment
Именно то, что мне было нужно. - person Grambo; 15.07.2020

один раздел работает, но если у вас больше одного раздела, это вызовет некоторые проблемы

person WuShuMin    schedule 12.10.2019