DecorationView получает изменение размера, если в UICollectionViewFlowLayout включено автоматическое изменение размера ячеек
среда:UICollectionView
это похоже на UITableView
Пользовательский подкласс UICollectionViewFlowLayout для определения frame
на DecorationView
Self-Sizing ячейки включены
ожидаемое поведение:
А DecorationView
это должно быть помещено в качестве фона для каждого раздела UICollectionView
Наблюдаемое Поведение:
The DecorationView
рухнет до произвольного размера:
кажется, что UICollectionView
пытается вычислить автоматический размер для DecorationView
. Если я отключить внутреннюю размеров клеток, вид украшения будет располагаться прямо в ожидаемом месте.
есть ли способ отключить Self-Sizing для DecorationView
?
в своем UICollectionViewFlowLayout
подкласс я просто беру первую и последнюю ячейки в разделе и растягиваю фон, чтобы заполнить пространство под ними. Проблема в том, что UICollectionView
не уважает размер вычисляется есть:
override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let collectionView = collectionView else {
return nil
}
let section = indexPath.section
let attrs = UICollectionViewLayoutAttributes(forDecorationViewOfKind: backgroundViewClass.reuseIdentifier(),
with: indexPath)
let numberOfItems = collectionView.numberOfItems(inSection: section)
let lastIndex = numberOfItems - 1
guard let firstItemAttributes = layoutAttributesForItem(at: IndexPath(indexes: [section, 0])),
let lastItemAttributes = layoutAttributesForItem(at: IndexPath(indexes: [section, lastIndex])) else {
return nil
}
let startFrame = firstItemAttributes.frame
let endFrame = lastItemAttributes.frame
let origin = startFrame.origin
let size = CGSize(width: startFrame.width,
height: -startFrame.minY + endFrame.maxY)
let frame = CGRect(origin: origin, size: size)
attrs.frame = frame
attrs.zIndex = -1
return attrs
}
2 ответов
возможно, что рамки ваших декоративных представлений не обновляются (т. е. недействительны) после того, как рамки ваших ячеек были саморазмерными. В результате ширина каждого вида украшения остается на уровне размера по умолчанию.
попробуйте реализовать эту функцию, которая должна аннулировать макет вида украшения для каждого раздела каждый раз, когда макет элемента в этом разделе недействителен:
override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
let invalidatedSections = context.invalidatedItemIndexPaths?.map { .section } ?? []
let decorationIndexPaths = invalidatedSections.map { IndexPath(item: 0, section: ) }
context.invalidateDecorationElements(ofKind: backgroundViewClass.reuseIdentifier(), at: decorationIndexPaths)
super.invalidateLayout(with: context)
}
Если вы хотите пользовательский размер для высоты и ширины в flowLayout вы можете использовать flowLayoutDelegate
и установите пользовательский размер для каждой ячейки в каждом разделе и т. д.
extension YourView: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let widthCell: CGFloat = 30.0
let heightCell: CGFloat = 50
let size: CGSize = CGSize(width: widthCell, height: heightCell)
return size
}
}