Kuroiteiken
Kuroiteiken

Reputation: 308

UICollection Cells are mixed in swift

I'm trying to generate cells and put labels inside of it. However, when i scroll down labels got mixed between cells. Here is my code and i'm trying to solve it.

    let lblTitle = UILabel()
    let lblMetro = UILabel()
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: indexPath) as? UICustomCollectionViewCell

        if indexPath.row == 0 {
            lblTitle.frame = CGRect(x: 0, y: 0, width: 195, height: 40)
            lblTitle.font = UIFont.systemFont(ofSize: 14)
            lblTitle.textColor = UIColor.white
            lblTitle.backgroundColor =  colorLiteral(red: 0.2122299671, green: 0.4379466176, blue: 0.8993332386, alpha: 1)
            lblTitle.text = "  1”
            cell?.contentView.addSubview(lblTitle)
            }

                if indexPath.row == 1 {
           lblMetro.frame = CGRect(x: 55, y: 290, width: 100, height: 20)
            lblMetro.font = UIFont.boldSystemFont(ofSize: 17)
            lblMetro.textColor =  colorLiteral(red: 0, green: 0.3117707968, blue: 0.5609284043, alpha: 1)
            lblMetro.text = “2”
            cell?.contentView.addSubview(lblMetro)
            }

    return cell ?? UICollectionViewCell()
    }
 }

Upvotes: 0

Views: 167

Answers (3)

Rohan Bhale
Rohan Bhale

Reputation: 1345

I suggest using a very rarely used method of UICollectionViewCell or UITableViewCell prepareForReuse. In definition of UICustomCollectionViewCell insert the function:

class UICustomCollectionViewCell: UICollectionViewCell {
    func prepareForReuse() {
        // This method is immediately called when a cell is about to be dequeued.
        super.prepareForReuse()
        if let view = contentView.viewWithTag(100) {
            view.removeFromSuperView()
        }

        if let view = contentView.viewWithTag(101) {
            view.removeFromSuperView()
        }
    }
}

Then give tags to the labels

lblMetro.tag = 100
lblTitle.tag = 101

This solution is efficient if you only use a limited labels and cells. For a more generic approach create labels dynamically and share the tag. In the prepareForReuse() just remove subview with that tag.

Upvotes: 1

Mumtaz Hussain
Mumtaz Hussain

Reputation: 1125

Not optimised but this might solve it, remove the subview from superview before adding it:

cell?.contentView.lblTitle.removeFromSuperview()
cell?.contentView.addSubview(lblTitle)

And:

cell?.contentView.lblMetro.removeFromSuperview()
cell?.contentView.addSubview(lblMetro)

Upvotes: 1

Shehata Gamal
Shehata Gamal

Reputation: 100543

Here cells are dequeued

var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: indexPath) as? UICustomCollectionViewCell

so you might get a 1 with previously added label , you need to clear them after dequeue , it would be messy but it's better to isolate the vc's labels from the cells 1 so add them inisde the cell configure or make them an outlets , to remove give them a tag and after the above line do

cell.contentView.subviews.forEach { 
   if $0.tag == 200 {
      $0.removeFromSuperview()
   }
}

Upvotes: 1

Related Questions