I have two collection views. Tapping unselected cells in Collection View 1 selects them, and adds the selected cell to Collection View 2. Tapping on selected cells in Collection View 1 (allHobbiesCV) will unselect them and remove them from Collection View 2 (myHobbiesCV). Essentially, all it's doing is toggling.
Cells in Collection View 2 can also be manually removed by selecting as few or many as desired, then pressing a 'Remove' button. This process works great, except the cells in Collection View 1 still remain selected, even if that particular cell was removed from Collection View 2.
How do I use the remove button to deselect cells from Collection View 1 if they were manually selected and removed from Collection View 2?
Class level -
var allHobbiesArray = [String]()
var allHobbiesArraySelected = [String]()
var myHobbiesArray = [String]()
var myHobbiesArraySelected = [String]()
didSelectItemAt
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// All Hobbies
if collectionView == allHobbiesCV {
let item = allHobbiesArray[indexPath.item]
let cell = allHobbiesCV.cellForItem(at: indexPath) as! AllHobbiesCell
if let itemIndex = allHobbiesArraySelected.index(of:item) {
// DID DESELECT
allHobbiesArraySelected.remove(at:itemIndex)
myHobbiesArray.remove(at: itemIndex)
myHobbiesCV.deleteItems(at: [IndexPath(item: itemIndex, section:0)])
cell.backgroundColor = UIColor.brown
}
else {
// DID SELECT
allHobbiesArraySelected.insert(item, at: 0)
myHobbiesArray.insert(item, at: 0)
myHobbiesCV.insertItems(at: [IndexPath(item: 0, section:0)])
cell.backgroundColor = UIColor.green
}
allHobbiesCV.deselectItem(at: indexPath, animated: false)
for cell in myHobbiesCV.visibleCells {
cell.backgroundColor = UIColor.white
}
myHobbiesArraySelected.removeAll()
//myHobbiesCV.reloadData() // needed?
}
// My Hobbies
else {
let item = myHobbiesArray[indexPath.item]
let cell = myHobbiesCV.cellForItem(at: indexPath) as! MyHobbiesCell
if let itemIndex = myHobbiesArraySelected.index(of:item) {
// DID DESELECT
myHobbiesArraySelected.remove(at: itemIndex)
cell.backgroundColor = UIColor.white
}
else {
// DID SELECT
myHobbiesArraySelected.insert(item, at: 0)
cell.backgroundColor = UIColor.red
}
myHobbiesCV.deselectItem(at: indexPath, animated: true)
}
}
cellForItem
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == allHobbiesCV {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ALL", for: indexPath) as! AllHobbiesCell
cell.allHobbiesCellLabel.text = allHobbiesArray[indexPath.item]
let allHobbies = allHobbiesArray[indexPath.item]
if allHobbiesArraySelected.index(of: allHobbies) != nil {
cell.backgroundColor = UIColor.green
}
else {
cell.backgroundColor = UIColor.brown
}
return cell
}
else { // myHobbiesCV
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MY", for: indexPath) as! MyHobbiesCell
cell.myHobbiesCellLabel.text = myHobbiesArray[indexPath.item]
let myHobbies = myHobbiesArray[indexPath.item]
if myHobbiesArraySelected.index(of: myHobbies) != nil {
cell.backgroundColor = UIColor.red
}
else {
cell.backgroundColor = UIColor.white
}
return cell
}
}
numberOfItemsInSection
if collectionView == allHobbiesCV {
return allHobbiesArray.count
}
else {
return myHobbiesArray.count
}
Delete button
@IBAction func deleteHobbyButtonPressed(_ sender: UIButton) {
print("all Hobbies - \(allHobbiesCV.indexPathsForSelectedItems!)")
if let selectedItemPaths = myHobbiesCV.indexPathsForSelectedItems {
var allItemIndexPaths = [IndexPath]()
var tempSelectedItems = Array(allHobbiesArraySelected) // Need to use a temporary copy otherwise the element indexes will change
for itemPath in selectedItemPaths {
let removeItem = allHobbiesArraySelected[itemPath.item]
if let removeIndex = tempSelectedItems.index(of: removeItem) {
print("if let removeIndex")
tempSelectedItems.remove(at: removeIndex)
}
if let allItemsIndex = allHobbiesArray.index(of: removeItem) {
print("if let allItemsIndex")
allItemIndexPaths.append(IndexPath(item: allItemsIndex, section: 0))
}
}
allHobbiesArraySelected = tempSelectedItems // Selected items array without the removed items
myHobbiesCV.deleteItems(at:selectedItemPaths)
myHobbiesCV.reloadData()
allHobbiesCV.reloadItems(at: allItemIndexPaths) // Reload to update the selected status
}
}
The problem now is nothing is evaluating in the remove button. That first print statement always returns an empty array. And nothing prints in the if let check. Is there a way to use myHobbiesArraySelected instead of indexPathsForSelectedItems? (Since I'm saving the selected items in an array now) Along with the original intended functionality of deselecting the cell in allHobbiesCV if it was manually deleted in myHobbiesCV.
Thanks friends.
It is a bad idea to store selected index paths, as these are coupled to the collection view. If you store the selected items then you can always determine the appropriate index path, using the item's index in the array. You can also determine an item quickly from a given index path.
In the code below I have used the type
Item
for your underlying item, but it could beString
orInt
or any object type. If you use your own class or struct, ensure you make it conform toEquatable
andHashable
.Update: IndexPath conforms
Equatable
(see comment from @Paulw11)you compare the objectsIndexPath
incontains
but but even if an instance ofindexPath
path have the same sections and rows the object itself is different.1. solution: compare values change the contains to to compare the sections and rowsi would suggest to implement solution 2