如Collection View Programming Guide for iOS中所述,如果要向Flow Layout添加新的补充视图或装饰视图,则必须继承UICollectionViewFlowLayout。
我需要帮助才能在Swift 3中实施以下步骤:
标准流布局类仅支持节标题和节页脚视图,不支持装饰视图。要支持其他补充和装饰视图,您至少需要覆盖以下方法:
- layoutAttributesForElementsInRect:(必填)
- layoutAttributesForItemAtIndexPath:(必填)
- layoutAttributesForSupplementaryViewOfKind:atIndexPath:(支持新的补充意见)
- layoutAttributesForDecorationViewOfKind:atIndexPath:(支持新的装饰视图)
在layoutAttributesForElementsInRect:方法中,您可以调用super来获取单元格的布局属性,然后为指定矩形中的任何新补充视图或装饰视图添加属性。使用其他方法按需提供属性。
我想实现的目标:
referenceSizeForHeaderInSection
的方法来定义集合视图控制器内的新补充视图的大小(return CGSize.zero
,如果不应该是"项目标题") 我知道这个问题的定义过于宽泛。但是在Devon和一些自己的想法的帮助下,我找到了一个适合我的解决方案。
子类 UICollectionViewFlowLayout
class SBCollectionViewFlowLayout: UICollectionViewFlowLayout { … }
覆盖layoutAttributesForElements(in rect: CGRect)
以向每个单元格添加其他补充视图。
// Check if there already valid layout attributes
guard var layoutAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
// Try to append new supplementary view to each cell
// ────────────────────────────────────────────────────────────
for attributes in layoutAttributes where attributes.representedElementCategory == .cell {
if let supplementaryAttributes = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindDateSeparator, at: attributes.indexPath) {
layoutAttributes.append(supplementaryAttributes)
}
}
return layoutAttributes
覆盖layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath)
以计算集合视图中新补充视图的位置。
switch elementKind {
case UICollectionElementKindDateSeparator:
// Return if there is no collection view or delegate
guard let delegate = self.collectionView?.delegate as? SBCollectionViewDelegateFlowLayout else { return nil }
// Get the dynamic size of from the delegate
let size = delegate.collectionView!(self.collectionView!, layout: self, referenceSizeForSeparatorAt: indexPath)
// Return if there the size is (0, 0)
if size == CGSize.zero { return nil }
// Create new layout attributes for the separator
// ════════════════════════════════════════════════════════════
let attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, with: indexPath)
if let itemAttributes = layoutAttributesForItem(at: indexPath) {
// Position supplementary view at top left edge of the cell
// ────────────────────────────────────────────────────────────
attributes.frame = CGRect(x: itemAttributes.frame.origin.x,
y: itemAttributes.frame.origin.y,
width: size.width,
height: size.height)
// Increase the item’s position on the z axis
// to be sure that the item appear on top of the cell.
attributes.zIndex = 1
}
return attributes
default:
// If it is not a date separator, return attributes from flow layout
return super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
}
"扩展和#34; UICollectionViewDelegateFlowLayout 向代表询问新标题的大小。
public protocol SBCollectionViewDelegateFlowLayout: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForSeparatorAt indexPath: IndexPath) -> CGSize
}
这个想法不是将附加的补充视图插入到集合视图中,然后重新计算所有项目,而是在相应的单元格顶部添加补充视图。向单元格添加动态顶部填充非常重要,补充视图不会覆盖单元格内的任何内容。
我希望这可以帮助其他人解决类似问题!