When a button gets tapped within a Collection View, the border color of the button gets updated to yellow and also reflects that it has been selected. If I tap on another button, I want to be able to update the border to yellow but also change the previous button's border to the original color black.
Attempted this solution: How to highlight selection only one button at a time from multiple buttons using Swift but was unable to change the previous button to the original color.
My current code
let buttonTitles: [String] = ["Red", "Blue", "Green", "Orange", "Gray"]
var isChosen: Bool = false
@objc func selectAction(_ sender: UIButton) {
let tag = sender.tag
print(tag)
isChosen = true
if tag == 1 {
sender.borderColor = .yellow
sender.borderWidth = 5
} else if tag == 2 {
sender.borderColor = .black
sender.borderWidth = 1
}
isChosen = !isChosen
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return buttonTitles.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colorsCollectionCell", for: indexPath) as! ColorsCollectionCell
cell.colorsButton.setTitle(timeOptions[indexPath.row], for: .normal)
cell.colorsButton.tag = indexPath.row
cell.colorsButton.addTarget(self, action: #selector(selectAction(_:)), for: .touchUpInside)
return cell
}
You can keep track of the selectedButton indexPath by declaring a variable:
var selectedButtonIndexPath: IndexPath?
Then inside cellForItemAt, you can define what the button looks like when selected:
if indexPath == selectedButtonIndexPath { // If button is selected
cell.colorsButton.layer.borderColor = UIColor.yellow.cgColor
cell.colorsButton.layer.borderWidth = 5
} else { // If it is not selected
cell.colorsButton.layer.borderColor = UIColor.black.cgColor
cell.colorsButton.layer.borderWidth = 1
}
Finally, inside your selectAction function:
@objc func selectAction(_ sender: UIButton) {
/* First let's get a reference to the cell that contains the newly selected button. Make sure you get the correct amount of superviews in there.. it depends on how you laid out your cells */
guard let newlySelectedButtonCell = sender.superview?.superview as? ColorsCollectionCell else { return }
// Let's find out the indexPath for the newly selected button
guard let newlySelectedButtonCellIndexPath = collectionView.indexPath(for: newlySelectedButtonCell) else { return }
// If previously selected button and newly selected button are the same, simply deselect button
if newlySelectedButtonCellIndexPath == selectedButtonIndexPath {
newlySelectedButtonCell.colorsButton.layer.borderColor = UIColor.black.cgColor
newlySelectedButtonCell.colorsButton.layer.borderWidth = 1
selectedButtonIndexPath = nil
return
}
// If newly selected button is different than previously selected button...
// First change the look for previously selected button
if let indexPath = selectedButtonIndexPath, let previouslySelectedButtonCell = collectionView.cellForItem(at: indexPath) as? ColorsCollectionCell {
newlySelectedButtonCell.colorsButton.layer.borderColor = UIColor.black.cgColor
newlySelectedButtonCell.colorsButton.layer.borderWidth = 1
}
// Now change the look of newly selected button
newlySelectedButtonCell.layer.borderColor = UIColor.yellow.cgColor
newlySelectedButtonCell.layer.borderWidth = 5
selectedButtonIndexPath = newlySelectedButtonCellIndexPath
}
There is an easier way to code the last function, and that would be to simply change the value of selectedButtonIndexPath and call reloadData() to update the collectionView. But it's not optimal:
@objc func selectAction(_ sender: UIButton) {
guard let newlySelectedButtonCell = sender.superview?.superview as? ColorsCollectionCell else { return }
guard let newlySelectedButtonCellIndexPath = collectionView.indexPath(for: newlySelectedButtonCell) else { return }
if newlySelectedButtonCellIndexPath != selectedButtonIndexPath {
selectedButtonIndexPath = newlySelectedButtonCellIndexPath
} else { // If same button selected, deselect? Unless you want a different behavior
selectedButtonIndexPath = nil
}
collectionView.reloadData()
}
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.