I’m working on collectionView and stuck on like when user tap on collectionView cell item it change the colour accordingly and other item colour also change.First cell item would be active and colour will be blue and other cell colour will be deactive and colour gray.But in my case the code not working fine see code below.
var category: [Category] = [
Category(cat: "For You"),
Category(cat: "Top chats"),
Category(cat: "Kids"),
Category(cat: "Categories"),
Category(cat: "Editor Choice")
]
var isSelected: Int? = nil {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
extension DashboardViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.isSelected = indexPath.row
}
}
extension DashboardViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return category.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
configureDashboardCell(collectionView, cellForItemAt: indexPath)
}
func configureDashboardCell(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: CategoryCell.self), for: indexPath) as? CategoryCell else {return UICollectionViewCell()}
cell.lblName.text = category[indexPath.item].cat
if self.isSelected == indexPath.row {
let textColor: UIColor = .blue
let underLineColor: UIColor = .blue
let underLineStyle = NSUnderlineStyle.single.rawValue
let labelAtributes:[NSMutableAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.underlineStyle: underLineStyle,
NSAttributedString.Key.underlineColor: underLineColor
]
let underlineAttributedString = NSAttributedString(string: cell.lblName.text ?? "",
attributes: labelAtributes)
cell.lblName.attributedText = underlineAttributedString
} else {
let textColor: UIColor = .gray
let labelAtributes:[NSMutableAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: textColor
]
let underlineAttributedString = NSAttributedString(string: cell.lblName.text ?? "",
attributes: labelAtributes)
cell.lblName.attributedText = underlineAttributedString
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (self.collectionView.bounds.width / 3) - 5 , height: 40)
}
}
2
Answers
Please use your selection in
willDisplayCell
. First let the cell to be in the view incellForRowAt
and then try to redesign the cell whatever you wish.and reload data when the cell is tapped
In my opinion, I would recomment you
isSelected
property to control all of the style.You should put all the task to cell, rather than directly control it through collectionView.
As you mentioned above,
so you just want two State, either
selected
ordeselected
, and one selected only.Let we have a try
collection.selectItem(at: <#T##IndexPath?#>, animated: <#T##Bool#>, scrollPosition: <#T##UICollectionView.ScrollPosition#>)
, it make cell callisSelected
twice both for new selected Cell and the old one needed to deselect.