Jtapplecalendar: Changes in cellForItemAt applying to other random cells

Created on 30 Apr 2017  路  6Comments  路  Source: patchthecode/JTAppleCalendar

Some of the changes that i am making in cellForItemAt are changing other random cells. Every time that i swipe left/right to change the month, this changes are applied to different cells and i have no idea why.

The changes that i am making basically consist in: If there is a workout at the cell date (I get this information from a database inside the app), get all the muscles trained at this workout and change the color from 4 views that i put inside the cell. This 4 views are _backgroundColor_ set to clear, and when there is a workout at the day, the method pick the first four muscles trained at this workout and then change the _backgroundColor_ from each view to purple. If there is less trained muscles than view, it let the others view _backgroundColor_ to clear.

A picture that easily illustrate the problem:
screen shot 2017-04-30 at 13 25 44

At days 30 and 6 i have no workout at, but the cell view that indicates the workout is colored with the color from the workout that i have registered at the cell from April 29. And if i swipe right and than left to come back from June month, the colored cells change randomly

screen shot 2017-04-30 at 13 28 04

The code that i am using at the method is below:

let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: "customCell", for: indexPath) as! CustomCell

cell.dateLabel.text = cellState.text
cell.cellDate = cellState.date

if database.existWorkoutAtDate(date: date.getOnlyDate) == true{
   var musclesTrained = database.getTrainingSectionOfDate(date: date.getOnlyDate)?.getMusclesTrained()
    if (musclesTrained?.count)!>=1 {
        cell.firstTrainingCircle.backgroundColor = musclesTrained?[0].color
   }
   if (musclesTrained?.count)!>=2{
      cell.secondTrainingCircle.backgroundColor = musclesTrained?[1].color
   }
   if (musclesTrained?.count)!>=3{
      cell.thirdTrainingCircle.backgroundColor = musclesTrained?[2].color
   }
   if (musclesTrained?.count)!>=4{
      cell.fourthTrainingCircle.backgroundColor = musclesTrained?[3].color
   }
}

 handleCellSelected(view: cell, cellState: cellState, date:date)
 handleCellTextColor(view: cell, cellState: cellState)

 if date.getOnlyDate == Date.init().getOnlyDate{
    cell.selectedView.isHidden = false
    cell.selectedView.backgroundColor = UIColor.red
 }

 return cell

The part the check the training and set the views colors is

if database.existWorkoutAtDate(date: date.getOnlyDate) == true {
   var musclesTrained = database.getTrainingSectionOfDate(date: date.getOnlyDate)?.getMusclesTrained()
   if (musclesTrained?.count)!>=1 {
      cell.firstTrainingCircle.backgroundColor = musclesTrained?[0].color
   }
   if (musclesTrained?.count)!>=2 {
      cell.secondTrainingCircle.backgroundColor = musclesTrained?[1].color
   }
   if (musclesTrained?.count)!>=3 {
      cell.thirdTrainingCircle.backgroundColor = musclesTrained?[2].color
   }
   if (musclesTrained?.count)!>=4 {
      cell.fourthTrainingCircle.backgroundColor = musclesTrained?[3].color
   }
}

Some considerations:

  1. I guarantee that the method existWorkoutAtDate it's working fine.
  2. I've put some breakpoints at lines cell.firstTrainingCircle.backgroundColor = musclesTrained?[0].color, cell.secondTrainingCircle.backgroundColor = musclesTrained?[1].color, cell.thirdTrainingCircle.backgroundColor = musclesTrained?[2].color and cell.fourthTrainingCircle.backgroundColor = musclesTrained?[3].color to get all the times that the method change any cells view color, and thats what is strange: it only changes it's once, at the day that i actually registered the training. At the random days that are colored, the method doesnt access the lines above, thats why i have no idea why they are getting colored, since the method are not accessing the lines.

All 6 comments

The cellForItem function behaves _exactly_ the same as UIKit UICollectionView's cellForItem function. There is no difference.

If you are seeing views repeated, then this is a symptom that you are not resetting the cells properly :)

cellForItem function is called for every cell that you see on the screen. Therefore you have to properly reset the cell

you have this many times

if (musclesTrained?.count)!>=1 {
      cell.firstTrainingCircle.backgroundColor = musclesTrained?[0].color
   }

but you are missing the else part

} else {
    cell.firstTrainingCircle.backgroundColor = nil
}

Therefore your cell is not properly reset.
This is more of a UICollectionView problem then a Calendar problem.

I understand. Just a question, what do you mean with "reset the cell" ? There is something that i have to do else fixing the if,if,if problem?

With a UICollectionView. Cells are reused.
Therefore the else part properly resets a cell.

If you do not have the else part, then you will have repeating views displaying because that cell would have been used before, and therefore would contain old data on it.

So is the issue now resolved?
I think i spoke about the repeating issue in this video -> https://www.youtube.com/watch?v=Qd_Gc67xzlw

Yep, you were right again! Thank you.

For those who may have the same issue, in the method cellForItemAt, before verifying if exist a training at the day, i set all the views brackgroundColor to nil

        cell.firstTrainingCircle.backgroundColor = nil
        cell.secondTrainingCircle.backgroundColor = nil
        cell.thirdTrainingCircle.backgroundColor = nil
        cell.fourthTrainingCircle.backgroundColor = nil

        if database.existWorkoutAtDate(date: date.getOnlyDate) == true{

            var musclesTrained = database.getTrainingSectionOfDate(date: date.getOnlyDate)?.getMusclesTrained()


            if (musclesTrained?.count)!>=1{
                cell.firstTrainingCircle.backgroundColor = musclesTrained?[0].color
            }
            if (musclesTrained?.count)!>=2{
                cell.secondTrainingCircle.backgroundColor = musclesTrained?[1].color
            }
            if (musclesTrained?.count)!>=3{
                cell.thirdTrainingCircle.backgroundColor = musclesTrained?[2].color
            }
            if (musclesTrained?.count)!>=4{
                cell.fourthTrainingCircle.backgroundColor = musclesTrained?[3].color
            }
        }

This solved my problem, and the explanation from why this was happening its on @patchthecode answer. Thank you ;)

Awesome. Closing this issue.
Till next time.
馃嵒

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sahirmemon picture sahirmemon  路  4Comments

dbmrq picture dbmrq  路  5Comments

programus picture programus  路  3Comments

blinkmeoff picture blinkmeoff  路  3Comments

leo150 picture leo150  路  3Comments