Last active
May 17, 2023 09:05
-
-
Save Lancewer/83f8ea7c3c3e6c82f28799f4888bd134 to your computer and use it in GitHub Desktop.
[Collection Single Selection] single selection in UICollectionView with swift #swift #UICollectionView #selection #select #single select
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
UICollectionView单选cell的解决方法 | |
解决了: | |
1. 单选时改变cell状态 | |
2. 单选状态的保存,避免cell重用时状态乱跳的问题 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//custom cell class | |
import UIKit | |
class CollectionViewCell: UICollectionViewCell { | |
@IBOutlet weak var nameLabel: UILabel! | |
override var isSelected: Bool{ | |
didSet(newValue){ | |
contentView.backgroundColor = newValue ? UIColor.green : UIColor.white | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ViewController: UIViewController { | |
//save the indexPath of last selected cell | |
var lastSelectedIndexPath:IndexPath? | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
override func didReceiveMemoryWarning() { | |
super.didReceiveMemoryWarning() | |
} | |
} | |
extension ViewController: UICollectionViewDelegate { | |
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { | |
//if selected item is equal to current selected item, ignore it | |
guard lastSelectedIndexPath != indexPath else { | |
return | |
} | |
if lastSelectedIndexPath != nil { | |
collectionView.deselectItem(at: lastSelectedIndexPath!, animated: false) | |
} | |
print("Selected:\(indexPath)") | |
let selectedCell = collectionView.cellForItem(at: indexPath) as! CollectionViewCell | |
selectedCell.isSelected = true | |
lastSelectedIndexPath = indexPath | |
} | |
} | |
extension ViewController: UICollectionViewDataSource { | |
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return 20 | |
} | |
func numberOfSections(in collectionView: UICollectionView) -> Int { | |
return 10 | |
} | |
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell | |
cell.nameLabel.text = "S\(indexPath.section)-R\(indexPath.row)" | |
//update last select state from lastSelectedIndexPath | |
cell.isSelected = (lastSelectedIndexPath == indexPath) | |
return cell | |
} | |
} |
override func viewDidLoad() {
collectionView.allowsMultipleSelection = false
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard lastIndex != indexPath else { return }
if let index = lastIndex {
let cell = collectionView.cellForItem(at: index) as? YourCell
cell?.isSelected = false
}
let cell = collectionView.cellForItem(at: indexPath) as? YourCell
cell?.isSelected = true
lastIndex = indexPath
}
This works 100%!!!
`In my case, I want to change the background of the button in other words the background of the cell in the collection view:
class CustomCVCell: UICollectionViewCell {
override var isSelected: Bool {
didSet {
grayBackgroundViewWithImage.image =
isSelected ? UIImage(named: "") : UIImage()
}
}
In the main class where the collection view is stored create this variable:
class CustomViewController: UIViewController {
///save the indexPath of last selected cell
private var lastSelectedIndexPath: IndexPath? }
In viewDidLoad() set this value to false:
customCollectionView.allowsMultipleSelection = false
Further code in data source. In my case, the first cell should be is selected:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCVCell.cellID(),
for: indexPath) as! CustomCVCell
if indexPath.row == 0 {
lastSelectedIndexPath = indexPath
cell.isSelected = true
}
//update last select state from lastSelectedIndexPath
cell.isSelected = (lastSelectedIndexPath == indexPath)
return cell
}
Further code in the delegate:
///UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard lastSelectedIndexPath != indexPath else { return }
if let index = lastSelectedIndexPath {
let cell = collectionView.cellForItem(at: index) as! CustomCVCell
cell.isSelected = false
}
let cell = collectionView.cellForItem(at: indexPath) as! CustomCVCell
cell.isSelected = true
lastSelectedIndexPath = indexPath
}
`
For constant index if scrolling.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCVCell.cellID(),
for: indexPath) as! CustomCVCell
if indexPath.row == 0 && lastSelectedIndexPath == nil {
lastSelectedIndexPath = indexPath
cell?.isSelected = true
} else {
cell?.isSelected = (lastSelectedIndexPath == indexPath)
}
return cell
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not working