In the following minimal example, I create a UICollectionView
with five UICollectionViewCell
s. For each, I create a CALayer
with the same frame
and set its backgroundColor
property and add it as a sublayer to the UICollectionViewCell
's layer
property. The cells initially on screen are set as expected, but the remaining cells may be the wrong color, and may disappear before entirely off screen when scrolling. This question [1] suggests that this is happening because the cells are not initially on screen (?), but I don't see from the answers how to fix the problem.
Below is a minimal working example. A few things I've tried are commented out:
- Set the cell's background color directly, to make sure this isn't a problem with the way I set up the collection view (it isn't).
- Calling
setNeedsDisplay()
(has no effect). - Removing the cell's layer's sublayers (crashes when scrolling).
import Foundation
import UIKit
enum Colors: Int {
case Red
case Orange
case Yellow
case Green
case Blue
}
class TestViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
var collectionView = UICollectionView(frame: CGRect(x: 100, y: 100, width: 100, height: 100), collectionViewLayout: UICollectionViewFlowLayout())
let reuseIdentifier = "ColorCell"
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.dataSource = self
self.collectionView.delegate = self
self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "ColorCell")
self.view.addSubview(self.collectionView)
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifier, forIndexPath: indexPath) as UICollectionViewCell
var l = CALayer()
l.frame = cell.frame
l.delegate = self
if let color = Colors(rawValue: indexPath.item) {
switch color {
case .Red:
l.backgroundColor = UIColor.redColor().CGColor
// cell.backgroundColor = UIColor.redColor()
case .Orange:
l.backgroundColor = UIColor.orangeColor().CGColor
// cell.backgroundColor = UIColor.orangeColor()
case .Yellow:
l.backgroundColor = UIColor.yellowColor().CGColor
// cell.backgroundColor = UIColor.yellowColor()
case .Green:
l.backgroundColor = UIColor.greenColor().CGColor
// cell.backgroundColor = UIColor.greenColor()
case .Blue:
l.backgroundColor = UIColor.blueColor().CGColor
// cell.backgroundColor = UIColor.blueColor()
}
} else {
l.backgroundColor = UIColor.blackColor().CGColor
// cell.backgroundColor = UIColor.redColor()
}
// for sub in cell.layer.sublayers {
// sub.removeFromSuperlayer()
// }
cell.layer.addSublayer(l)
// cell.setNeedsDisplay()
return cell
}
}