2

我开发了一个自定义 CollectionViewLayout 用于DecorationView显示单元格后面的阴影。

但是,我只想将此装饰添加到某些单元格。是,但它可能包含嵌入在单元格内的UICollectionView内容。如图所示,不应装饰带有嵌入的单元格:verticalhorizontal UICollectionViewUICollectionView

在此处输入图像描述

这是我用来添加阴影的代码。没有提供如何检索单元格的类的UICollectionViewLayout方法,因此它可以决定是否添加阴影:

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

    let sections = attributes.map{$0.indexPath.section}
    let unique = Array(Set(sections))


    // Need to detect, which sections contain an embedded UICollectionView and exclude them from the UNIQUE set


    let backgroundShadowAttributes: [UICollectionViewLayoutAttributes] = unique.compactMap{ section in
      let indexPath = IndexPath(item: 0, section: section)
      return self.layoutAttributesForDecorationView(ofKind: backgroundViewClass.reuseIdentifier(),
                                                    at: indexPath)
    }

    return attributes + backgroundShadowAttributes + separators
  }

有没有办法有条件地指定应该装饰哪些视图?

4

1 回答 1

3

完成这段代码:一个直接询问数据源的协议,是否为特定部分显示阴影:

protocol SectionBackgroundFlowLayoutDataSource {
  func shouldDisplayBackgroundFor(section: Int) -> Bool
}

并利用func layoutAttributesForElements(in rect: CGRect)方法中的协议:

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

    attributes.forEach(configureRoundCornersAttributes)

    // Display shadows for every section by default
    var sectionsWithShadow = Set(attributes.map{$0.indexPath.section})
    if let dataSource = collectionView?.dataSource as? SectionBackgroundFlowLayoutDataSource {
    // Ask DataSource for sections with shadows, if it supports the protocol
      sectionsWithShadow = sectionsWithShadow.filter{dataSource.shouldDisplayBackgroundFor(section: $0)}
    }

    let backgroundShadowAttributes: [UICollectionViewLayoutAttributes] = sectionsWithShadow.compactMap{ section in
      let indexPath = IndexPath(item: 0, section: section)
      return self.layoutAttributesForDecorationView(ofKind: backgroundViewClass.reuseIdentifier(),
                                                    at: indexPath)
    }

    return attributes + backgroundShadowAttributes + separators
  }

func shouldDisplayBackgroundFor(section: Int) -> Bool可能会比 更快地返回cellForItemAtIndexPath,因为它不需要完整的单元配置。

于 2018-04-13T12:04:02.783 回答