Invalidate и Redraw CAShapeLayer внутри collectionViewCell после изменения ориентации устройства - PullRequest
0 голосов
/ 05 июля 2018

У меня есть пользовательская ячейка представления коллекции, которая добавляет пунктирную границу к слою со следующим кодом:

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"?

1 Ответ

0 голосов
/ 05 июля 2018

Поскольку ячейки можно использовать повторно, каждый вызов 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()
    }
}

Надеюсь, это поможет.

...