I struggled thro the same problem where I wanted to display photos and allow the user to select multiple photos, with select-all and deselct-all options.
It turned out that [self.collectionView selectItemAtIndexPath:] does not work for selecting all cells.
So I ended up in maintaining a separate state flag along with the data source. In my case, each cell displayed a photo, so I had to maintain a separate BOOL array, where each element represents the current selection state of the corresponding photo in the data source array.
Please see the code below:
(Source: http://heliumapps.weebly.com/blog/uicollectionview-and-cell-selection)
@interface PhotosViewController() {
BOOL *selectedStates; //cell selection states boolean array [C-language array]
/* Let us assume that we have an array for data source, named "myDataSourceArray".
For each element in the array, the correspomding element in selectedStates represents
the selection state of the cell.
*/
}
//load data source
-(void)loadDataSource {
//init the data source array (myDataSourceArray) and populate it with data
//free up the previously allocated memory for selecteStates, if any (in case you reuse this view controller)
if(selectedStates) {
free(selectedStates);
selectedStates = nil;
}
//initilaize the selection states of all cells to NO
selectedStates = malloc(myDataSourceArray.count*sizeof(BOOL));
for(NSUInteger i = 0; i < self.myDataSourceArray.count; i++) {
selectedStates[i] = NO;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PhotoViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:self.reuseIdentifier
forIndexPath:indexPath];
//populate cell with required data & images to display
[cell setPhoto:myDataSourceArray[indexPath.item]];
//configure cell for selection state
[cell configureCellForSelectionState:selectedStates[indexPath.item]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[self toggleSelectionOfCellAtIndex:indexPath];
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
[self toggleSelectionOfCellAtIndex:indexPath];
}
-(void)toggleSelectionOfCellAtIndex:(NSIndexPath*)indexPath{
MyCollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
selectedStates[indexPath.item] = !selectedStates[indexPath.item];
[cell configureForSelectionState];
}
//method to select/deselect all photos
- (void) setStateForAllPhotos:(BOOL)flag {
for(NSUInteger i = 0; i < self.myDataSourceArray.count; i++) {
selectedStates[i] = flag;
}
[self.collectionView reloadData]; //on main thread
}
/* below method in the cell's implementation */
-(void) configureForSelectionState:(BOOL)flag {
if(flag) {
//configure cell for selected state
[cell.layer setBorderColor:[UIColor greenColor].CGColor];
[cell.layer setBorderWidth:2];
} else {
//configure cell for deselected state
}
}