fphelp
fphelp

Reputation: 1636

Changing ImageView Based on Selection In A CollectionView

I currently have a CollectionView with 1 reusable cell where it's filled up with a ImageView. This cell is used 10 times to show 10 different animals (I provide the pics for the cell). I also have a label above this collection view. Every time a user presses on a cell, the label will change to "Name of the animal selected". What I now want is for the cell image to get darker when it's selected and go back to normal when it's not selected. As of now I know how to change the image of the cell to a darker one by manually switching it with a darker one, but I do not know how to change it back to normal as I pick on another one. How do I implement this? I have copied my code at the bottom:

//cell configuration
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        //define the cell
        let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! AnimalSelectionCell

        //animals is name of array of different types of animals
        cell.animalImage.image = UIImage(named: animals[indexPath.row])
        cell.animalImage.restorationIdentifier = animals[indexPath.row]

        return cell
    }

    //choosing an animal
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {        
            let currentCell = collectionview.cellForItem(at: indexPath) as! AnimalSelectionCell
            let animal = currentCell.animalImage.restorationIdentifier! //gets what type of animal selected
            selectionLabel.text = "\(animal) selected" //changes label
            currentCell.animalImage.image = UIImage(named: animal + "Selected") //changes to darker animal image                 
        }

Upvotes: 2

Views: 1904

Answers (2)

Reinier Melian
Reinier Melian

Reputation: 20804

You can define a var called selectedIndexpath and in your didSelectItemAt method change by the selected indexpath, if the selectedIndexPath is the same you should make selectedIndexpath to nil and in your cellForItemAt method you only need to check if the current indexPath is equal to your selectedIndexpath property

var selectedIndexPath : IndexPath? //declare this

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        //define the cell
        let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! AnimalSelectionCell

        //animals is name of array of different types of animals
        cell.animalImage.image = UIImage(named: animals[indexPath.row])
        if(indexPath == selectedIndexPath){
            //if indexpath is selected use your darker image
            cell.animalImage.image = UIImage(named: animal + "Selected")
        }
        cell.animalImage.restorationIdentifier = animals[indexPath.row]
        return cell
    }

    //choosing an animal
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {        
            let currentCell = collectionview.cellForItem(at: indexPath) as! AnimalSelectionCell
            let animal = currentCell.animalImage.restorationIdentifier! //gets what type of animal selected
            selectionLabel.text = "\(animal) selected" //changes label
            var prevSelectedIndexPath : IndexPath?
            if(selectedIndexPath != nil){
                 if(selectedIndexPath == indexPath){
                     selectedIndexPath = nil
                 }else{
                     prevSelectedIndexPath = IndexPath(row: selectedIndexPath.row, section: selectedIndexPath.section)
                     selectedIndexPath = indexPath
                 }
            }else{
                selectedIndexPath = indexPath
            }

            if(prevSelectedIndexPath != nil){
                 collectionView.reloadItems(at: [indexPath,prevSelectedIndexPath])
            }else{
                 collectionView.reloadItems(at: [indexPath])
            }
        }

func clearSelection(){
    if(selectedIndexPath != nil){
         let prevSelectedIndexPath = IndexPath(row: selectedIndexPath.row, section: selectedIndexPath.section)
         selectedIndexPath = nil
         self.collectionView.reloadItems(at: [prevSelectedIndexPath])
    }
}

Upvotes: 1

Daniel
Daniel

Reputation: 3597

In order to do this, you must subclass UICollectionViewCell and override the isSelected property:

class MyCell: UICollectionViewCell {
    override var isSelected {
        willSet(bool) {
            self.backgroundColor = UIColor.gray // or whatever
        }
    }
}

Upvotes: 1

Related Questions