CollectionView Cell order messes up on scroll

I’m trying to alternate the color of my collection view cells like this: enter image description here

But when I scroll down and then scroll back up, all the cells get reordered like this:

enter image description here

This is my code:

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 100
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "yearlyBookshelfCell", for: indexPath) as! yearlyBookshelfCell
            cell.bookLabel.text = "\(indexPath.item)"
            if indexPath.item % 2 != 0 {               
                cell.bookView.backgroundColor = .darkGray
        return cell

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let width  = (view.frame.width)
            return CGSize(width: view.frame.width/11, height: view.frame.width/3)


>Solution :

This is a common problem with new iOS developers and table views/collection views.

The rule: When you return a cell in your cellForItemAt/cellForRowAt method, you always need to fully configure the cell. Don’t assume it comes to you as a blank page.

Your if statement says if indexPath.item % 2 != 0 (if the item count is even) then set the background color to gray.

What if the item value is odd? You leave it whatever color it was to start with. I’m guessing that your cells start out with a blue background color. But, what if this is a recycled cell that was gray last time it was used?

The way your code is written, that cell will fall through the if statement and its (gray) background color won’t get changed..

You need an else clause:

        if indexPath.item % 2 != 0 {               
            cell.bookView.backgroundColor = .darkGray
        } else {
            cell.bookView.backgroundColor = .blue // Or whatever the default color is

And you need to do that for every single property of your cell that might ever change. If every 100th cell gets a box around it, then you need to write code that removes the box if it’s not one of those rare 1 out of 100 cells, or you will wind up picking up a recycled cell that has a box around it from the last time it was used.

Leave a Reply