Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CollectionView multiple cell selection

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()
}
like image 478
Hashem Al-Issa Avatar asked Sep 18 '16 14:09

Hashem Al-Issa


2 Answers

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
}
like image 183
Aerows Avatar answered Sep 27 '22 01:09

Aerows


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

like image 39
Tiago Oliveira Avatar answered Sep 26 '22 01:09

Tiago Oliveira