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.