ios - UICollectionViewLayout:仅将 DecorationView 添加到特定单元格

标签 ios uicollectionview uicollectionviewlayout uicollectionreusableview uicollectionviewflowlayout

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

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

enter image description here

这是我用来添加阴影的代码。 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
  }

有什么方法可以有条件地指定应该装饰哪些 View ?

最佳答案

用这段代码完成: 直接询问数据源是否显示特定部分的阴影的协议(protocol):

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

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

  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 返回更快,因为它不需要完整的单元格配置。

关于ios - UICollectionViewLayout:仅将 DecorationView 添加到特定单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49814431/

相关文章:

iphone - UICollectionView 单元格重叠

ios - UICollectionView 异步更新大小

ios - 是否有 UIImage imageWithCGImage :scale:orientation: method? 或错误的文档和错误的方法?

ios - 使用 AVFoundation 混合图像和视频

ios - 如何快速正确地从另一个 Controller 访问一个 Controller 变量和方法?

ios - 删除收藏的单元格

ios - 如何在 uicollectionview 中设置我的 UIButton 标题

iphone - 验证可用的网络连接和启用定位服务以使用应用程序

ios - 如何在一个 collectionView 中使用多个项目数组?

IOS - 粘性 UICollectionView header (如 Apple App Store)