Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting all the items in UICollectionView iOS, even the cells that are not visible

I am in the middle of creating an application where I have a button on a tool bar which selects all the items inside a collection view.

But the problem that I am facing is, when I tap on the button it selects only those items that are visible on the screen. This is due to the CELL REUSE functionality.

Is there any way that I can select all the cells, even those which are not currently visible to the user?

Thanks J

like image 741
Akhilesh Sharma Avatar asked Nov 11 '13 22:11

Akhilesh Sharma


People also ask

What is the difference between UITableView and UICollectionView?

For the listing details of each item, people use UITableView because it shows more info on each item. The UICollectionView class manages an ordered collection of data items and presents them using customizable layouts.

What is the use of datasource and delegate in UICollectionView in IOS?

This method asks the data source object to provide a supplementary view to display in the collection view. It asks the datasource object whether the specified item can be moved to another location in the collectionview. This method moves the specified item to the specified indexpath.

How does UICollectionView work?

From apple's documentation, UICollectionView is: An object that manages an ordered collection of data items and presents them using customizable layouts. The name and definition makes it clear, it is a way to display a Collection of UI Views in our app. The individual view is referred as a Cell.


2 Answers

This is possible even with cell reuse. You can select all cells in the first section through:

for (NSInteger row = 0; row < [self.collectionView numberOfItemsInSection:0]; row++) {
    [self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:NO scrollPosition:UICollectionViewScrollPositionNone];
}

If you have more than 1 section, just use another nested for loop to loop through all the sections.

like image 191
Gasper Avatar answered Oct 19 '22 22:10

Gasper


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
    }
}
like image 23
Kabeer Avatar answered Oct 20 '22 00:10

Kabeer