Home > OS >  Set Background Color of specific CollectionView Cells according to IndexPath
Set Background Color of specific CollectionView Cells according to IndexPath

Time:12-22

I'm pretty new to Swift and programming in general, so sorry for the simple question:

I want to develop a calendar that uses an (horizontally scrollable) UICollectionView as interface. Every cell of the UICollectionView is supposed to have a label with the number of the respective day and the weekday.

For this purpose I have an dateArray that stores the date-objects. The setupCell- method is putting the respective data onto the labels of the UICollectionViewCell.

Cells that show Sundays should be highlighted by having a different background-color than the other cells.

I tried to implement this functionality in the cellForItemAt - method, but got stuck there.

My function looks like this:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.identifier, for: indexPath) as! MyCollectionViewCell
        

        let dayFormatter = DateFormatter()
        let weekdayFormatter = DateFormatter()
        dayFormatter.dateFormat = "dd"
        weekdayFormatter.dateFormat = "EEE"

        cell.setupCell(day: dayFormatter.string(from: dateArray[indexPath.item]), weekday: weekdayFormatter.string(from: dateArray[indexPath.item]))

    
        
        if Calendar.current.component(.weekday, from: dateArray[indexPath.item]) == 1   {
            cell.backgroundColor = UIColor.gray
        }

        
        return cell
    } 

With this function the Sundays are highlighted as planned, but only as long as I don't scroll. After some scrolling at the end all cells will be highlighted.

I'm thankful for every hint to solve the issue.

CodePudding user response:

The UICollectionViewCells are being reused. Hence the name dequeueReusableCell. This means that, for example, the cell at index 0 is the same cell is at index 30. When you have set the color of the cell at index 0 to UIColor.gray, the cell at 30 will also be gray, unless you set it to another color. Because all cells are going to be reused, and all cells will eventually be a "Sunday" at some point, they will all become colored.

There is an easy fix for this, do not only set a color for the ones you want to have a color but also do the opposite.

For example:

if Calendar.current.component(.weekday, from: dateArray[indexPath.item]) == 1 {
    cell.backgroundColor = UIColor.gray
} else {
    cell.backgroundColor = UIColor.white
}

I haven't tried it myself before, but there seems to be another way to achieve this as well. You could also implement the prepareForReuse() (docs) method in the UICollectionViewCell itself. You could do this by adding the following to the cell:

override func prepareForReuse() {
    super.prepareForReuse()
    backgroundColor = UIColor.white // Or set to another color you want
}

Another method would be to set the backgroundColor in the setupCell() you created for your cell. This will be called every time a cell is reused, so this might be an excellent place to do this as well. Just apply the same logic as above (if Sunday -> gray, else -> white).

  • Related