简体   繁体   English

在 Swift iOS 中选择 collectionView Cell 时更改 label 颜色

[英]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.我正在尝试在我的应用程序中按类型创建过滤器,并且我进行了 collectionView 设置,并且一切正常。

my only problem is making the collectionView cells text labels change color when they are selected to white, and black when they are not.我唯一的问题是让 collectionView 单元格文本标签在被选中时更改颜色为白色,而在未选中时更改为黑色。

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.首先,您不应该在cellForItemAt添加子视图 ... 单元格被重用,并且最终在每个单元格中多次添加子视图。

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无需在控制器中对didSelectItemAtdidDeselectItemAt执行任何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.在子类 UICollectionViewCell 的单元格中,只需通过标签上的highlightedTextColor属性设置颜色突出显示和正常状态。

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. 1): 内部单元格添加视图和一个 label。

2): Create outlet for both. 2):为两者创建出口。

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

3): In you collectionView cell class paste the following code. 3): 在您的 collectionView 单元格 class 中粘贴以下代码。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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