Reputation: 715
I have a slide-out menu that I have implemented as a UICollectionViewController. I have created custom cells for the collection view as well. The navigation and everything works as expected. What I am having trouble with is changing the cells appearance when I click on an actual cell.
I've tried several approaches based on solutions(1)(2) I've seen here on stack but nothing to my satisfaction.
Solution 1: implement the UICollectionViewController delegate methods:
class SlideOutMenuViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
//Setup code and other delegate methods….
override func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SlideOutMenuCells
cell.backgroundColor = .white
}
override func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SlideOutMenuCells
cell.backgroundColor = UIColor.mainGreen()
}
}
When I tried this solution, nothing happens. The cells background color doesn't change colors.
Solution 2: This solution results in better results except the cell on changes colors when I hold the cell. I'd like the cells background color to flash or highlight quickly on a tap and not really just if the user holds the cell down.
class SlideOutMenuCells: UICollectionViewCell {
//Setup code...
override var isHighlighted: Bool {
didSet {
if self.isHighlighted {
backgroundColor = UIColor.darkGreen()
} else {
backgroundColor = UIColor.mainGreen()
}
}
}
}
Neither solution really works as intended. I've seen several posts here that try addressing this but haven't found one with a solution that works really. I would like the cell to flash highlight with a tap, and not just when a user clicks and holds on a cell...
Upvotes: 16
Views: 10193
Reputation: 3924
Here is working code for highlighting UICollectionViewCell
on tap (swift 4 | swift 5)
In your view controller, add
collectionView.delaysContentTouches = false
class StoreCollViewCell:UICollectionViewCell{
override var isHighlighted: Bool {
didSet {
if self.isHighlighted {
backgroundColor = UIColor.green
} else {
backgroundColor = UIColor.yellow
}
}
}
}
Output
Upvotes: 15
Reputation: 1339
I had only to remove the highlight on the collectionViews when tapped.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: IDSActionList.reuseIdentifier, for: indexPath) as? IDSActionList else {
return
}
cell.contentView.backgroundColor = .white
self.collectionView.reloadData()
}
Upvotes: 0
Reputation: 5940
I had the exact same problem and the solution is actually much simpler then the one posted above.
In your view controller, add collectionView.delaysContentTouches = false
.
And then your other code within the cell was fine as is:
class SlideOutMenuCells: UICollectionViewCell {
//Setup code...
override var isHighlighted: Bool {
didSet {
if self.isHighlighted {
backgroundColor = UIColor.green
} else {
backgroundColor = UIColor.red
}
}
}
}
But now that annoying delay is gone!
Upvotes: 16
Reputation: 139
You can do this by changing the color if content view in cell like:
class SlideOutMenuCells: UICollectionViewCell {
override var isSelected: Bool {
didSet {
self.contentView.backgroundColor = isSelected ? OLTheme.Colors.Selected_Voucher_Color : UIColor.clear
}
}
}
Upvotes: 1
Reputation: 602
You can try to use UILongPressGestureRecognizer
to indicate selection:
override func awakeFromNib() {
super.awakeFromNib()
let tapGesture = UILongPressGestureRecognizer(target: self, action: #selector(didTap(recognizer:)))
tapGesture.minimumPressDuration = 0
tapGesture.cancelsTouchesInView = false
addGestureRecognizer(tapGesture)
}
@objc func didTap(recognizer: UILongPressGestureRecognizer) {
if recognizer.state == .began {
backgroundColor = .red
}
if recognizer.state == .ended {
backgroundColor = .green
}
}
or you can make extension
for UICollectionViewCell
extension UICollectionViewCell {
func makeSelectionIndicatable() {
let tapGesture = UILongPressGestureRecognizer(target: self, action: #selector(didTap(recognizer:)))
tapGesture.minimumPressDuration = 0
tapGesture.cancelsTouchesInView = false
addGestureRecognizer(tapGesture)
}
@objc private func didTap(recognizer: UILongPressGestureRecognizer) {
if recognizer.state == .began {
backgroundColor = .red
}
if recognizer.state == .ended {
backgroundColor = .green
}
}
}
and after that for any cell at awakeFromNib()
method you just need to add makeSelectionIndicatable()
Upvotes: 3