9

环境:
UICollectionView看起来像 UITableView
自定义 UICollectionViewFlowLayout 子类来定义启用frameDecorationView
Self-Sizing 单元格

预期行为:
ADecorationView应该作为每个部分的背景放置UICollectionView

预期行为

观察到的行为:
折叠DecorationView到任意大小:

观察到的行为

似乎UICollectionView试图计算DecorationView. 如果我禁用 Self-Sizing 单元格,则装饰视图将准确放置在预期位置。

有什么方法可以禁用 Self-Sizing forDecorationView吗?

在我的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
}
4

2 回答 2

5

在您的单元格的框架已自行调整大小后,您的装饰视图的框架可能没有更新(即无效)。结果是每个装饰视图的宽度保持在其默认大小。

尝试实现此功能,每次该部分中的项目布局无效时,它应该使每个部分的装饰视图的布局无效:

override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
    let invalidatedSections = context.invalidatedItemIndexPaths?.map { $0.section } ?? []
    let decorationIndexPaths = invalidatedSections.map { IndexPath(item: 0, section: $0) }
    context.invalidateDecorationElements(ofKind: backgroundViewClass.reuseIdentifier(), at: decorationIndexPaths)
    super.invalidateLayout(with: context)
}
于 2018-03-08T02:23:57.697 回答
1

如果您想在 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
        }
    }
于 2018-03-05T07:14:32.063 回答