UICollectionViewLayout:仅将 DecorationView 添加到特定单元格
UICollectionViewLayout: add DecorationView only to specific cells
我开发了一个自定义 CollectionViewLayout,它使用 DecorationView
来显示单元格后面的阴影。
但是,我只想将此装饰添加到某些单元格。 UICollectionView
是 vertical
,但它可能在单元格内包含嵌入的 horizontal
UICollectionView
。嵌入 UICollectionView
的单元格不应修饰,如图所示:
这是我用来添加阴影的代码。 UICollectionViewLayout
没有提供如何获取单元格的 class 的方法,因此它可以决定是否添加阴影:
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{[=10=].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
}
有什么方法可以有条件地指定哪些视图应该被装饰?
完成此代码:
直接询问数据源的协议,是否为特定部分显示阴影:
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{[=11=].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: [=11=])}
}
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
可能 return 比 cellForItemAtIndexPath
快,因为它不需要完整的单元配置。
我开发了一个自定义 CollectionViewLayout,它使用 DecorationView
来显示单元格后面的阴影。
但是,我只想将此装饰添加到某些单元格。 UICollectionView
是 vertical
,但它可能在单元格内包含嵌入的 horizontal
UICollectionView
。嵌入 UICollectionView
的单元格不应修饰,如图所示:
这是我用来添加阴影的代码。 UICollectionViewLayout
没有提供如何获取单元格的 class 的方法,因此它可以决定是否添加阴影:
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{[=10=].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
}
有什么方法可以有条件地指定哪些视图应该被装饰?
完成此代码: 直接询问数据源的协议,是否为特定部分显示阴影:
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{[=11=].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: [=11=])}
}
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
可能 return 比 cellForItemAtIndexPath
快,因为它不需要完整的单元配置。