John
John

Reputation: 183

How to add border to UICollectionViewCell on didSelect and remove that border on select another UICollectionViewCell?

I UICollectionView with 10 cells, for example. I want to add border to the selected cell, later, on select another cell, want to remove previous border and add a border to the new selected cell.

How can I achieve this?

I've tried this:

var selected = [NSIndexPath]()
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    self.imageView.image = applyFilter(self.colorCubeFilterFromLUT("\(self.LUTs[indexPath.row])")!, image: self.image!)

    self.selected.append(indexPath)
}

func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
    let cell = self.filtersCollectionView.cellForItemAtIndexPath(indexPath) as! FiltersCollectionViewCell
    cell.imageView.layer.borderWidth = 3.0
    cell.imageView.layer.borderColor = UIColor.brownColor().CGColor
}

func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {

    if self.selected.count > 1 && indexPath == self.selected[self.selected.count - 1] {            
        let cell = self.filtersCollectionView.cellForItemAtIndexPath(indexPath) as! FiltersCollectionViewCell
        cell.imageView.layer.borderWidth = 0.0
        cell.imageView.layer.borderColor = UIColor.clearColor().CGColor
    }
}

but it does not work. What I do wrong?

Upvotes: 9

Views: 10727

Answers (4)

Aalaa
Aalaa

Reputation: 57

SWIFT 5

   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
         cell.imageView.layer.borderWidth = 2
         cell.imageView.layer.borderColor = UIColor.blue.cgColor
    
    }
    
    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
     
         cell.imageView.layer.borderWidth = 2
         cell.imageView.layer.borderColor = UIColor.clear.cgColor
    }

Upvotes: 0

Leonardo Garcia
Leonardo Garcia

Reputation: 71

There is a more simple solution, you can already use the functionality that the UICollectionView provides itself. In addition, it is better in performance as you don't have to reload the collectionView every time a single cell is selected. Apple suggest that you must only use reloadData() when your model actually changes.

You can override the property isSelected of UICollectionViewCell, then you only have to customize its appearance with a property observer:

override var isSelected: Bool {
    didSet {
        if isSelected {
            layer.borderWidth = 2
        } else {
            layer.borderWidth = 0
        }
    }
}

Just remind that you have to set layer.borderColor either within the cell initializer or where you consider convenient

PS: If later you want to do multiple selection, you will just have to enable the property allowsMultipleSelection in the collectionView

Upvotes: 7

Attia Mo
Attia Mo

Reputation: 35

Swift 3 version :

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

        var borderColor: CGColor! = UIColor.clear.cgColor
        var borderWidth: CGFloat = 0

        if indexPath == selectedIndexPath{
            borderColor = UIColor.brown.cgColor
            borderWidth = 1 //or whatever you please
        }else{
            borderColor = UIColor.clear.cgColor
            borderWidth = 0
        }

        cell.imageView.layer.borderWidth = borderWidth
        cell.imageView.layer.borderColor = borderColor 

   }

Upvotes: 0

kye
kye

Reputation: 2246

You could save the selected indexPath into a variable and within cellForItemAtIndexPath check if the current indexPath is equal to the selected index path (You would need to reload your collectionView each time its selected)

var selectedIndexPath: NSIndexPath{
    didSet{
        collectionView.reloadData()
    }
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedIndexPath = indexPath
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    var borderColor: CGColor! = UIColor.clearColor().CGColor
    var borderWidth: CGFloat = 0

    if indexPath == selectedIndexPath{
        borderColor = UIColor.brownColor().CGColor
        borderWidth = 1 //or whatever you please
    }else{
       borderColor = UIColor.clearColor().CGColor
        borderWidth = 0
    }

    cell.imageView.layer.borderWidth = borderWidth
    cell.imageView.layer.borderColor = borderColor
}

Upvotes: 6

Related Questions