5

I have a collection view with two custom cells one is for grid and one is for list, i want to be able to touch cells and select them as as if want to delete or share them , all i want for now to be able to select and deselct them, ill post my code below the result is when i touch one cell all cells are selected! here is the code:

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

        let cell:cell2_Class = collectionView.dequeueReusableCellWithReuseIdentifier("cell2", forIndexPath: indexPath) as! cell2_Class

        cell.listImage.image = imageArray[indexPath.row]

        if flag == true {
            cell.layer.borderColor = UIColor.blueColor().CGColor
            cell.layer.borderWidth = 3
            cancelButton.hidden = false
        } else {
            cell.layer.borderColor = UIColor.clearColor().CGColor
            cancelButton.hidden = true
        }
        return cell
    } else {
        let cell:PhotoCollectionCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! PhotoCollectionCell

        if flag == true {
            cell.layer.borderColor = UIColor.blueColor().CGColor
            cell.layer.borderWidth = 3
            cancelButton.hidden = false
        } else {
            cell.layer.borderColor = UIColor.clearColor().CGColor
            cancelButton.hidden = true
        }
        cell.imageView.image = imageArray[indexPath.row]
        cell.NameLabel.text = namelabel[indexPath.row]
        cell.ModifiedLbl.text = modfLabel[indexPath.row]

        return cell
    }
}

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

    let cell = collectionView.cellForItemAtIndexPath(indexPath)

    if cell!.selected == true {
        flag = true
    } else {
        flag = false 
    }
    self.collectionView.reloadData()
}
Jay Patel
  • 2,642
  • 2
  • 18
  • 40
Hashem Al-Issa
  • 51
  • 1
  • 1
  • 5

2 Answers2

13

In PhotoCollectionCell and cell2_Class (or in a common superclass) simply override this method

- (void) setSelected:(BOOL)selected 
{ 
     if (selected) 
     {        
         self.layer.borderColor = UIColor.blueColor().CGColor
         self.layer.borderWidth = 3
     } 
     else 
     {
         self.layer.borderColor = UIColor.clearColor().CGColor
     }
}

Then you don't have to deal with the actual selection/highlighting in your delegate or dataSource.

Make sure to have your collectionView has the property allowsSelection to YES.

If you want multiple selection then also set allowsMultipleSelection to YES and implement the following method in your delegate

- (BOOL) collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if ([collectionView.indexPathsForSelectedItems containsObject: indexPath])
    {
        [collectionView deselectItemAtIndexPath: indexPath animated: YES];
        return NO;            
    }
    return YES;
}

Swift Solution

Subclass of collectionViewCell

override var selected: Bool {
    didSet {
        self.layer.borderWidth = 3.0
        self.layer.borderColor = selected ? UIColor.blueColor().CGColor : UIColor.clearColor().CGColor
    }
}

in UICollectionViewDelegate:

func collectionView(collectionView: UICollectionView, shouldSelectItemAt indexPath: NSIndexPath) -> Bool {
    if let selectedItems = collectionView.indexPathsForSelectedItems() {
        if selectedItems.contains(indexPath) {
            collectionView.deselectItemAtIndexPath(indexPath, animated: true)
            return false
        }
    }
    return true
}
Aerows
  • 760
  • 6
  • 22
  • 1
    Thanks alot , but can you tell me how to do that in swift, thanks agan – Hashem Al-Issa Sep 19 '16 at 06:28
  • My swift is not up to my objective c standards, but this example should do it! =) – Aerows Sep 19 '16 at 07:35
  • thanks alot man, i did implement the solution you gave me but nothing happens when i touch a cell – Hashem Al-Issa Sep 19 '16 at 08:20
  • Thank you all for your help :) ,, followed this solution and it worked thank u all again :) http://stackoverflow.com/questions/28596859/swift-uicollectionviewcell-didselectitematindexpath-change-backgroundcolor?rq=1 – Hashem Al-Issa Sep 19 '16 at 09:05
4

Based on Aerows solution Swift 4.2

Subclass of collectionViewCell

override var isSelected: Bool {
        didSet {
            self.layer.borderWidth = 3.0
            self.layer.borderColor = isSelected ? UIColor.blue.cgColor : UIColor.clear.cgColor
        }
    }

in UICollectionViewDelegate

func collectionView(_ collectionView: UICollectionView, shouldDeselectItemAt indexPath: IndexPath) -> Bool {
    if let selectedItems = collectionView.indexPathsForSelectedItems {
        if selectedItems.contains(indexPath) {
            collectionView.deselectItem(at: indexPath, animated: true)
            return false
        }
    }
    return true
}

And very important, on your viewDidLoad() don't forget to allow your collectionView multiple selection

collectionView.allowsMultipleSelection = true

Apple documentation - allowsMultipleSelection

Tiago Oliveira
  • 329
  • 4
  • 7