简体   繁体   中英

Change label color when collectionView Cell is selected in Swift iOS

I am trying to create a filter by type in my app and I did the collectionView setup and everything is working perfectly.

my only problem is making the collectionView cells text labels change color when they are selected to white, and black when they are not.

but it doesn't seem to be working correctly, as it changes the color of a cell that is not selected and does not clear the color after it has been deselected.

Any help with this?

Thank you.

here is my code:

var label:UILabel!
var typeText:String?
var type = ["All","Coffee Shops","Pizza Places","Restaurants","Desserts"]


extension HomeTableViewController: UICollectionViewDataSource {
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return type.count
    }
    func numberOfSections(in collectionView: UICollectionView) -> Int {
    
        return 1
        
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
        
        let type = self.type[indexPath.row]
      
        cardView = UIView(frame: CGRect(x:0, y:0, width:myCell.frame.size.width, height:myCell.frame.size.height))
        cardView.backgroundColor = UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.02)
        cardView.layer.cornerRadius = 8
        cardView.layer.shadowOffset = CGSize(width: 0.2, height: 0.2)
        cardView.layer.shadowRadius = 1
        cardView.layer.shadowOpacity = 0.4
        cardView.layer.borderColor = CGColor(red:0.00, green:0.00, blue:0.00, alpha:0.2)
        cardView.layer.borderWidth = 0.4
        cardView.autoresizesSubviews = true
        cardView.clipsToBounds = true
        
        label = UILabel(frame: CGRect(x:0, y:0, width:cardView.frame.size.width, height:cardView.frame.size.height))
        label.textAlignment = .center
        label.textColor = UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.8)
        label.font = UIFont.systemFont(ofSize: 9, weight: .semibold)
        label.text = type
        
        myCell.addSubview(cardView)
        cardView.addSubview(label)
        
        return myCell
    }
}

extension HomeTableViewController: UICollectionViewDelegate {
 
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      
        typeText = self.type[indexPath.row]
        
        let backgroundView = UIView()
        backgroundView.backgroundColor = UIColor(red: 0.99, green: 0.71, blue: 0.25, alpha: 1.00) /*ffb233 feb947  fcb53f*/
        backgroundView.layer.cornerRadius = 8
        backgroundView.layer.shadowOffset = CGSize(width: 0.3, height: 0.3)
        backgroundView.layer.shadowRadius = 1
        backgroundView.layer.shadowOpacity = 0.4
        backgroundView.layer.borderColor = UIColor.white.cgColor
        backgroundView.layer.borderWidth = 0.5
        backgroundView.autoresizesSubviews = true
        backgroundView.clipsToBounds = true

        
       if let selectedCell:UICollectionViewCell = collectionView.cellForItem(at: indexPath){
        selectedCell.selectedBackgroundView = backgroundView
        label.textColor = .white
        }
}

   func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        let cellToDeselect:UICollectionViewCell = collectionView.cellForItem(at: indexPath)!
        cellToDeselect.contentView.backgroundColor = UIColor.clear
        label.textColor = .black
    }

First, you should not be adding subviews in cellForItemAt ... cells are reused, and you end up adding the subviews multiple times in each cell.

Instead, add your subviews in your cell class when it is instantiated.

Then, add this to your cell class:

override var isSelected: Bool {
    didSet {
        label.textColor = isSelected ? .white : .black
    }
}

No need to do anything in your controller on didSelectItemAt or didDeselectItemAt


Edit -- here is a very simple example...

The cell class:

class MyCardCell: UICollectionViewCell {
    let label: UILabel = {
        let v = UILabel()
        return v
    }()
    let cardView: UIView = {
        let v = UIView()
        return v
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        
        cardView.backgroundColor = UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.02)
        cardView.layer.cornerRadius = 8
        cardView.layer.shadowOffset = CGSize(width: 0.2, height: 0.2)
        cardView.layer.shadowRadius = 1
        cardView.layer.shadowOpacity = 0.4
        cardView.layer.borderColor = CGColor(red:0.00, green:0.00, blue:0.00, alpha:0.2)
        cardView.layer.borderWidth = 0.4
        cardView.clipsToBounds = true
        
        label.textAlignment = .center
        label.textColor = UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.8)
        label.font = UIFont.systemFont(ofSize: 9, weight: .semibold)

        [cardView, label].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
        }
        cardView.addSubview(label)
        contentView.addSubview(cardView)
        
        let g = contentView.layoutMarginsGuide
        
        NSLayoutConstraint.activate([
            
            cardView.topAnchor.constraint(equalTo: g.topAnchor),
            cardView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            cardView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            cardView.bottomAnchor.constraint(equalTo: g.bottomAnchor),

            label.centerYAnchor.constraint(equalTo: cardView.centerYAnchor),
            label.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 12.0),
            label.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -12.0),

        ])
    
    }
    
    override var isSelected: Bool {
        didSet {
            label.textColor = isSelected ? .white : .black
            // see the difference between setting
            //      cardView.backgroundColor
            //  or
            //      contentView.backgroundColor
            cardView.backgroundColor = isSelected ? UIColor(red: 0.99, green: 0.71, blue: 0.25, alpha: 1.00) : UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.02)
            //contentView.backgroundColor = isSelected ? UIColor(red: 0.99, green: 0.71, blue: 0.25, alpha: 1.00) : UIColor(red:0.00, green:0.00, blue:0.00, alpha:0.02)
        }
    }
}

and a sample view controller class:

class TestCardCollectionVC: UIViewController {
    
    var collectionView: UICollectionView!

    var type: [String] = ["All","Coffee Shops","Pizza Places","Restaurants","Desserts"]

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let fl = UICollectionViewFlowLayout()
        fl.scrollDirection = .horizontal
        fl.minimumLineSpacing = 0
        fl.minimumInteritemSpacing = 0
        fl.estimatedItemSize = CGSize(width: 50, height: 40)

        collectionView = UICollectionView(frame: .zero, collectionViewLayout: fl)
        
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(collectionView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: g.topAnchor),
            collectionView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            collectionView.heightAnchor.constraint(equalToConstant: 40.0)
        ])

        collectionView.backgroundColor = .systemBackground
        
        collectionView.register(MyCardCell.self, forCellWithReuseIdentifier: "cardCell")

        collectionView.dataSource = self
        collectionView.delegate = self
    }
    
}

extension TestCardCollectionVC: UICollectionViewDataSource, UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return type.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let c = collectionView.dequeueReusableCell(withReuseIdentifier: "cardCell", for: indexPath) as! MyCardCell
        c.label.text = type[indexPath.item]
        return c
    }

}

The output on launch (no cell selected):

在此处输入图片说明

selecting the 3rd cell:

在此处输入图片说明

selecting the 4th cell:

在此处输入图片说明

I tried to find solution using my own project. May be you should try this

class NatureCollectionViewCell: UICollectionViewCell {

@IBOutlet weak var natureItemsImage: UIImageView!
@IBOutlet weak var natureItemsNameLable: UILabel!


// This part you will need. just change the labels name
override var isSelected: Bool {
    
    didSet {
        if self.isSelected {
            self.natureItemsNameLable.textColor = .white
            
        } else {
            self.natureItemsNameLable.textColor = .black
        }
    }
}

}

In your cell that subclasses UICollectionViewCell simply set the color highlighted and normal states via the highlightedTextColor property on the label.

class TypeCell: UICollectionViewCell {

      @IBOutlet weak var titleLabel: UILabel!

      override func awakeFromNib() {
         super.awakeFromNib()
         titleLabel.textColor = .white
         titleLabel.highlightedTextColor = .green
      }
 }

1): Inside cell add view and a label.

2): Create outlet for both.

@IBOutlet weak var titleLabel : UILabel!
@IBOutlet weak var cellBgView: UIView!

3): In you collectionView cell class paste the following code.

 override var isSelected: Bool {
        didSet {
            titleLabel.textColor = isSelected ? .white : .black
            cellBgView.backgroundColor = isSelected ? .AppRed : .systemBackground
           
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM