Reputation: 53
My collection view have multiple section. What I'm trying to achieve is that user can only select one cell (answer) in each section. When the cell (answer) have been selected, the background color will change.
What i failed to do is that Example : when user click on a cell in section 1, I want to deselect only the other cell in section 1.
Below are some of my code
@IBOutlet var step3CollectionView: UICollectionView!
var HexColor = HexColorClass()
var dataPageThree : json_PageThree!
var step3AnswerArray : [Int] = []
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
var frameCount = dataPageThree.step_instruction.first!.subquestions.count
for i in 0..<frameCount{
if indexPath.section == i {
step3AnswerArray[i] = (dataPageThree.step_instruction.first?.subquestions[i].subquestion_selection_answerNums![indexPath.row])!
let callCell = self.step3CollectionView.cellForItem(at: indexPath) as? Step3CollectionViewCell
callCell!.answerLabel.backgroundColor = HexColor.hexStringToUIColor(hex: "117577")
callCell!.answerLabel.textColor = UIColor.white
}
}
}
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
let indexPaths = collectionView.indexPathsForSelectedItems
if (indexPaths?.count) ?? 0 > 0 {
/// If you need simple way
for index in indexPaths! {
if index.section == indexPath.section {
self.step3CollectionView.deselectItem(at: index, animated: true) // if want deselect previous selection
let callCell = self.step3CollectionView.cellForItem(at: index) as? Step3CollectionViewCell
callCell!.answerLabel.backgroundColor = UIColor.white
callCell!.answerLabel.textColor = UIColor.black
//return false //if you do not want further selection
}
}
}
return true
}
Need some guidance.
Upvotes: 2
Views: 4161
Reputation: 24341
First of all, set the collectionView's
allowsMultipleSelection
property to true
, i.e.
override func viewDidLoad() {
super.viewDidLoad()
self.step3CollectionView.allowsMultipleSelection = true
}
Now, the UICollectionViewDelegate
method collectionView(_: shouldSelectItemAt:)
should look like,
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
collectionView.indexPathsForSelectedItems?.filter({ $0.section == indexPath.section }).forEach({ collectionView.deselectItem(at: $0, animated: false) })
return true
}
Also, don't change the backgroundColour
of the cell
in shouldSelectItemAt
or didSelectItemAt
based on cell's
selection.
That makes the code bulky and redundant.
It should be done within the UICollectionViewCell
subclass by overriding isSelected
property.
class Step3CollectionViewCell: UICollectionViewCell {
override var isSelected: Bool {
didSet {
self.answerLabel.backgroundColor = isSelected ? HexColor.hexStringToUIColor(hex: "117577") : .white
self.answerLabel.textColor = isSelected ? .white : .black
}
}
}
With the above code, there is no need to write the color
change code in collectionView(_:didSelectItemAt:)
method as well. The UI for selection and de-selection of the cell
will be automatically handled.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
step3AnswerArray[indexPath.section] = (dataPageThree.step_instruction.first?.subquestions[i].subquestion_selection_answerNums![indexPath.row])!
}
Upvotes: 6