Положение прокрутки сбрасывается при reloadData при вычислении динамического размера заголовка

#ios #swift #uicollectionview

#iOS #swift #uicollectionview

Вопрос:

У меня есть big UIcollectionView с некоторой пользовательской логикой, и в его заголовке у меня есть другой UICollectionView с направлением прокрутки, установленным на горизонтальное. Кроме того, у меня есть другие метки внутри этого представления заголовка. Я получаю динамическую высоту заголовка следующим образом:

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    let indexPath = IndexPath(row: 0, section: section)
    let headerView = self.collectionView(collectionView, viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader, at: indexPath)
    
    let desiredWidth = collectionView.frame.width > 0 ? collectionView.frame.width : UIScreen.main.bounds.width
    return headerView.systemLayoutSizeFitting(CGSize(width: desiredWidth, height: UIView.layoutFittingExpandedSize.height),
                                                      withHorizontalFittingPriority: .required, // Width is fixed
                                                      verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
}
 

Высота вычисляется правильно, но если я прокручиваю горизонтальный CollectionView, а затем откуда-то из кода вызывается reloadData, его положение прокрутки сбрасывается.
Я знаю, что это происходит из-за let headerView = self.collectionView(collectionView, viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader, at: indexPath) этой строки, но есть ли какой-либо способ сохранить динамическую высоту заголовка и не сбрасывать прокрутку?

Комментарии:

1. Вы пробовали устанавливать переменную с текущим положением смещения представления коллекции каждый раз, когда оно прокручивается (что может быть зафиксировано в методах делегирования представления прокрутки)? Вы могли бы сделать это как минимум, а затем установить положение смещения содержимого при возврате представления заголовка, которое, я полагаю, вы установили бы в дополнительном методе просмотра, а не в методе компоновки, но я могу ошибаться.

Ответ №1:

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

 if let headerView = self.headerView {
   return headerView.systemLayoutSizeFitting(
                    CGSize(width: desiredWidth, height: UIView.layoutFittingExpandedSize.height),
                    withHorizontalFittingPriority: .required, // Width is fixed
                    verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
}
            
return CGSize(width: desiredWidth, height: 1)