0

Following is the collection view delegate function that I am using to render items with gradient view.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    collectionView.layoutIfNeeded()

    let collectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell

    let gradient = CAGradientLayer()

    gradient.frame = collectionView.bounds

    gradient.startPoint = CGPoint(x: 0.0, y: 0.5)

    gradient.endPoint = CGPoint(x: 1.0, y: 0.5)

    if indexPath.row % 2 == 0 {
        gradient.colors = [UIColor(hex: 0xD74F9B).cgColor, UIColor(hex: 0xF1828A).cgColor]
    } else {
        gradient.colors = [UIColor(hex: 0x5368D3).cgColor, UIColor(hex: 0x4AAAD1).cgColor]
    }

    collectionViewCell.cardView.layer.insertSublayer(gradient, at: 0)

    return collectionViewCell
}

When the collection view is loaded, I get the following view, in which one of the collection view items gets clipped. enter image description here

However, as I scroll the collection view, I get the properly rendered view. enter image description here

How can this issue be fixed?

Sujal
  • 1,447
  • 19
  • 34
  • Don't do `collectionViewCell.cardView.layer.insertSublayer(gradient, at: 0)`, cells are reused. Instead use a property of your custom cell `var gradient`. Init/Insert it in awakFromNib of cellInit (depending if you registered xib or class). Update its frame when cells layout did change, and only update its color in cellForRowAt. – Larme Dec 06 '18 at 11:35
  • See -> https://stackoverflow.com/a/52603164/6630644 – SPatel Dec 06 '18 at 13:18

1 Answers1

0

The problem is When you add the gradient view the bgView is not layout completely. So the bound will be zero.

Solution:

 // CollectionViewCell.swift
private var gradient: CAGradientLayer?

override func awakeFromNib() {
     super.awakeFromNib()
}

    override func layoutSubviews() {
        super.layoutSubviews()

        shadowView.layer.shadowPath = UIBezierPath(rect: shadowView.bounds).cgPath

        if let gradient = gradient {
            gradient.frame = bgView.bounds
        } else {
            gradient = CollectionViewCell.createGradientLayer(for: bgView)
            bgView.layer.addSublayer(gradient!)
        }
    }
Lal Krishna
  • 15,485
  • 6
  • 64
  • 84