项目中,经常需要用到九宫格布局的 CollectionView ,这时可能就需要给各个 Cell 添加边线,以与其他 Cell 隔开。
想到的有几种方案:
- 在 Cell 的初始化方法里,添加以下代码
self.layer.borderColor = ...
self.layer.borderWidth = 1
缺点:不过这种方式会让相邻的 Cell 的边线为两倍的边线宽度,作为开发者来说,明显是不能接受的。
2.使用 xib 与 InterfaceBuilder 方式创建的 Cell,在 xib 里拉四个 view ,设置好约束,充当 Cell 的 subviews 来当作分割线使用,然后在通过拉 IBOutlet,控制四个 view 的 hidden 属性,来控制边线的显示
缺点:每次需要边线的 Cell, 都会做类似无聊的操作
3.定义一个能控制边线的 CollectionView Cell 的基类,需要添加边线就继承此基类,从而简化工作量。
struct LWLineSeparatorOptions: OptionSetType {
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
static let top = LWLineSeparatorOptions.init(rawValue: 1)
static let bottom = LWLineSeparatorOptions.init(rawValue: 2)
static let left = LWLineSeparatorOptions.init(rawValue: 4)
static let right = LWLineSeparatorOptions.init(rawValue: 8)
}
class LWLineSeparatorCollectionViewCell: UICollectionViewCell {
var linwSeparatorOptions: LWLineSeparatorOptions = [.top, .bottom, .left, .right] {
didSet {
let _ = contentView.layer.sublayers!.map {
if $0.isKindOfClass(CAShapeLayer.self) {
$0.removeFromSuperlayer()
}
}
setNeedsDisplay()
}
}
var lineColor = UIColor.init(red: 224.0/255.0, green: 224.0/255.0, blue: 224.0/255.0, alpha: 0.7)
override func drawRect(rect: CGRect) {
super.drawRect(rect)
if linwSeparatorOptions.contains(.top) {
let layer = CAShapeLayer()
layer.lineWidth = 1
layer.borderWidth = 1
layer.strokeColor = lineColor.CGColor
let path = UIBezierPath.init()
path.moveToPoint(CGPointMake(0, 0))
path.addLineToPoint(CGPointMake(rect.size.width, 0))
layer.path = path.CGPath
contentView.layer.addSublayer(layer)
}
if linwSeparatorOptions.contains(.bottom) {
let layer = CAShapeLayer()
layer.lineWidth = 1
layer.borderWidth = 1
layer.strokeColor = lineColor.CGColor
let path = UIBezierPath.init()
path.moveToPoint(CGPointMake(0, rect.size.height))
path.addLineToPoint(CGPointMake(rect.size.width, rect.size.height))
layer.path = path.CGPath
contentView.layer.addSublayer(layer)
}
if linwSeparatorOptions.contains(.left) {
let layer = CAShapeLayer()
layer.lineWidth = 1
layer.borderWidth = 1
layer.strokeColor = lineColor.CGColor
let path = UIBezierPath.init()
path.moveToPoint(CGPointMake(0, 0))
path.addLineToPoint(CGPointMake(0, rect.size.height))
layer.path = path.CGPath
contentView.layer.addSublayer(layer)
}
if linwSeparatorOptions.contains(.right) {
let layer = CAShapeLayer()
layer.lineWidth = 1
layer.borderWidth = 1
layer.strokeColor = lineColor.CGColor
let path = UIBezierPath.init()
path.moveToPoint(CGPointMake(rect.size.width, 0))
path.addLineToPoint(CGPointMake(rect.size.width, rect.size.height))
layer.path = path.CGPath
contentView.layer.addSublayer(layer)
}
}
}
然后可以在delegate中这样使用:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(...)
switch indexPath.item / 3 {
case 0:
cell.linwSeparatorOptions = [.top, .right]
case 1:
cell.linwSeparatorOptions = [.top, .right]
case 2:
cell.linwSeparatorOptions = [.top, .right, .bottom]
default:
{}()
}
...
return cell
}