前言
在对UICollectionView的一个section进行布局时,主要可以分为四个区:header、footer、cell以及空白区,如下图
在这四个区中,cell点击系统提供了事件,header和footer也可以直接在view上添加点击处理,但是空白区,并不能直接处理点击。在我们做一些类似社区的项目时,难免会需要监听空白区的点击,接下来将介绍如何处理空白区的点击。
1.自定义UICollectionViewLayoutAttributes
/// section装饰背景的布局属性
class SLSectionDecorationViewCollectionViewLayoutAttributes: UICollectionViewLayoutAttributes {
//装饰背景图
var tapView = UIView()
/// 所定义属性的类型需要遵从 NSCopying 协议
/// - Parameter zone:
/// - Returns:
override func copy(with zone: NSZone? = nil) -> Any {
let copy = super.copy(with: zone) as! SLSectionDecorationViewCollectionViewLayoutAttributes
copy.tapView = self.tapView
return copy
}
/// 所定义属性的类型还要实现相等判断方法(isEqual)
/// - Parameter object:
/// - Returns: 是否相等
override func isEqual(_ object: Any?) -> Bool {
guard let rhs = object as? SLSectionDecorationViewCollectionViewLayoutAttributes else {
return false
}
if self.tapView != rhs.tapView {
return false
}
return super.isEqual(object)
}
}
2.自定义UICollectionReusableView
class SLSectionBackgroundReusableView: UICollectionReusableView {
static let BACKGAROUND_CID = "BACKGAROUND_CID"
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .clear
}
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
guard let att = layoutAttributes as? SLSectionDecorationViewCollectionViewLayoutAttributes else {
return
}
att.tapView.frame = bounds
addSubview(att.tapView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
3.自定义UICollectionViewFlowLayout
既然系统没提供空白区的点击监听,那么我们就重新布局配置数据,把我们自定义的view添加上去,通过处理view来处理空白区。
// 布局配置数据
override func prepare() {
super.prepare()
。。。。。。
let attrs = SLSectionDecorationViewCollectionViewLayoutAttributes(forDecorationViewOfKind: SLSectionBackgroundReusableView.BACKGAROUND_CID, with: IndexPath(item: 0, section: section))
attrs.frame = sectionFrame
attrs.zIndex = -1
attrs.tapView = delegate.collectionView(self.collectionView!, layout: self, decorationTapViewForSectionAt: section)
。。。。。。
}
}
4.提供入口,设置空白区的view
创建UICollectionView时,设置自定义layout,并设置代理,实现以下方法
protocol SLSectionDecorationLayoutDelegate: NSObjectProtocol {
/// 指定section点击View
///
/// - Parameters:
/// - collectionView: collectionView
/// - collectionViewLayout: layout
/// - section: section
/// - Returns: UIView
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: SLSectionDecorationLayout,
decorationTapViewForSectionAt section: Int) -> UIView
}
5.效果
当点击空白区域时,输出