在 Swift iOS 中选择 collectionView 单元格时更改标签颜色

Change label color when collectionView Cell is selected in Swift iOS

我正在尝试在我的应用程序中按类型创建过滤器,并且我进行了 collectionView 设置并且一切正常。

我唯一的问题是让 collectionView 单元格文本标签在被选中时更改颜色为白色,在未选中时更改为黑色。

但它似乎无法正常工作,因为它会更改未选中的单元格的颜色,并且在取消选中后不会清除颜色。

有什么帮助吗?

谢谢。

这是我的代码:

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
    }

首先,你不应该在 cellForItemAt 中添加子视图......单元格被重复使用,你最终会在每个单元格中多次添加子视图。

而是在实例化时将子视图添加到单元格 class 中。

然后,将其添加到您的单元格中 class:

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

didSelectItemAtdidDeselectItemAt

上无需在您的控制器中执行任何操作

编辑 -- 这是一个非常简单的例子...

单元格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)
        }
    }
}

和一个示例视图控制器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
    }

}

启动时的输出(未选择单元格):

选择第三个单元格:

选择第 4 个单元格:

我尝试使用我自己的项目找到解决方案。也许你应该试试这个

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
        }
    }
}

}

在子类 UICollectionViewCell 的单元格中,只需通过标签上的 highlightedTextColor 属性 设置颜色突出显示和正常状态。

class TypeCell: UICollectionViewCell {

      @IBOutlet weak var titleLabel: UILabel!

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