我有一个自定义的集合视图单元格,它使用以下代码向单元格层添加虚线边框:

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”内部?

最佳答案

因为单元格是可重用的,所以每次调用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()
    }
}

我希望这有帮助。

关于swift - 在设备方向更改后,在collectionViewCell内部无效并重绘CAShapeLayer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51198788/

10-10 08:47