1

I am having issues with displaying a checkmark on the a custom cell in a UICollectionView. For the first few taps everything works as expected, but when I begin scrolling or tapping repeatedly or click on the already selected cell, the behavior becomes odd as shown in the gif. Perhaps I am going about this in an incorrect way? The .addCheck() and .removeCheck() are methods inside the custom UICollectionViewCell class I made and all they do is add a checkmark image or remove one from the cell view. The odd behavior shown here

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! ColorUICollectionViewCell

    // Configure the cell
    let color = colorList[(indexPath as NSIndexPath).row]
    cell.delegate = self
    cell.textLabel.text = color.name
    cell.backgroundColor = color.color

    if color.selected {
        cell.addCheck()
    }
    else {
        cell.removeCheck()
    }

    return cell
}

// user selects item
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    // set colors to false for selection
    for color in colorList {
        color.selected = false
    }

    // set selected color to true for selection
    let color = colorList[indexPath.row]
    color.selected = true
    settings.backgroundColor = color.color
    //userDefaults.set(selectedIndex, forKey: "selectedIndex")
    collectionView.reloadData()
}

Below is what the addCheck() and removeCheck() functions in my custom cell look like.

func addCheck() {
    // create check image
    let checkImage = UIImage(named: "checkmark")
    checkImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: bounds.size.height / 4, height: bounds.size.height / 4))
    checkImageView.image = checkImage!.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
    checkImageView.tintColor = UIColor.white()

    // add the views
    addSubview(checkImageView)
}

func removeCheck() {
    if checkImageView != nil {
        checkImageView.removeFromSuperview()
    }
}
Lee
  • 913
  • 2
  • 7
  • 12
  • I've had similar issues with a `UITableView` when I use checkmarks. Try to create an Array of tuples to store row and section values. http://stackoverflow.com/questions/27918584/uitableview-checkmarks-disappear-when-scrolling – Sami Jun 28 '16 at 03:59

1 Answers1

1

first off, you can simplify your didSelect a bit:

override func collectionView(collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    // set colors to false for selection
    for (index, color) in colorList.enumerate() {
        if index == indexPath.row {
            color.selected = false
            settings.backgroundColor = color.color
        }
        else {
            color.selected = false
        }
    }

    collectionView.reloadData()
}

Based on the language in your cellForItemAt method, I'm guessing you're adding a second check mark image when you tap on the same cell twice, and it's not being tracked properly so that cell just keeps getting rotated around overtime the collectionView's reloaded

Post your cell class, or at least the logic for addCheck and removeCheck and we might find the problem.

What I would recommend is permanently having an imageView with the check mark over the cell, when simple show/hide it based on the selection. This should speed up the collectionView as well.

GetSwifty
  • 7,568
  • 1
  • 29
  • 46
  • Thanks for taking a look. I added the addCheck() and removeCheck() functions to my quesiton. – Lee Jun 28 '16 at 04:30
  • I tried doing the method of overlaying a checkmark on each cell as they initialize and then hiding the image instead of removing it and it seems to be working fine. Thank you very much! – Lee Jun 28 '16 at 04:37
  • 1
    great! It does look like you would've ended up with multiple images floating around – GetSwifty Jun 28 '16 at 05:19