我有一个自定义集合视图单元格,该单元格使用以下代码在单元格层中添加了虚线边框:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = appDealCollectionView.dequeueReusableCell(withReuseIdentifier: "appDealCollectionCell", for: indexPath) as! AppDealCollectionViewCell
if let codes = discountCodes {
cell.discountCodeTitle.text = codes[indexPath.row].codeMessageOne
cell.discountCode.text = codes[indexPath.row].code
let yourViewBorder = CAShapeLayer()
yourViewBorder.strokeColor = UIColor.black.cgColor
yourViewBorder.lineWidth = 2
yourViewBorder.lineDashPattern = [10, 10]
yourViewBorder.frame = cell.bounds
yourViewBorder.fillColor = nil
yourViewBorder.path = UIBezierPath(roundedRect: cell.bounds, cornerRadius: 6).cgPath
cell.layer.addSublayer(yourViewBorder)
}
return cell
}
此代码在视图的初始加载时效果很好。但是,当方向改变时,像元大小也会改变。上面的代码确实正确绘制了新的边框CAShapeLayer,但是仍然存在基于旧尺寸绘制的先前绘制的边框层。
结果是同时存在两个不同的边界层,它们相互重叠且尺寸不同。
如何使以前绘制的CAShapeLayers无效?无效在哪里做?在cellForItemAt中?还是可能在自定义“ AppDealCollectionViewCell”内部?
答案 0 :(得分:2)
由于单元格是可重用的,因此每次调用cellForRowAtIndexPath
都会在单元格上添加CAShapeLayer
的另一个实例。这就是为什么您有多个相互重叠的边界。另外,CALayer
不支持自动布局,也不支持autoresizingMask
,因此您必须手动更新CAShapeLayer
的大小。
您应该创建UITableViewCell
的子类,然后创建CAShapeLayer
的实例并将其指针存储在类属性变量中。一旦发生布局周期,就需要在layoutSubviews
函数中更新CAShapeLayer
的框架。
最终实现如下:
class BorderedTableViewCell: UITableViewCell {
lazy var borderLayer = CAShapeLayer()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupBorderLayer()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupBorderLayer()
}
private func setupBorderLayer() {
borderLayer.strokeColor = UIColor.black.cgColor
borderLayer.lineWidth = 2
borderLayer.fillColor = nil
borderLayer.lineDashPattern = [10, 10]
layer.addSublayer(borderLayer)
}
private func updateBorderLayer() {
borderLayer.frame = bounds
borderLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 6).cgPath
}
override func layoutSubviews() {
super.layoutSubviews()
updateBorderLayer()
}
}
我希望这会有所帮助。