Use a button on a UICollectionViewCell to display data from an array Use a button on a UICollectionViewCell to display data from an array xcode xcode

Use a button on a UICollectionViewCell to display data from an array


I have made my own subclass of UICollectionViewCell for the nib file that I use for all of the UICollectionViewCells, and connected the button to the .h file as a IBAction.

If you connect the IBAction to the subclass of collectionViewCell you would need to create a delegate to make the touch event available in the viewController where you are displaying the data.

One easy tweak is to add the button the collectionViewCell, connect it's IBOutlet to the cell. But not IBAction. In the cellForRowAtIndexPath: add an eventHandler for button in that viewController containing collectionView.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{    //Dequeue your cell    [cell.button addTarget:self                     action:@selector(collectionViewCellButtonPressed:)          forControlEvents:UIControlEventTouchUpInside];    return cell;}- (IBAction)collectionViewCellButtonPressed:(UIButton *)button{    //Acccess the cell    UICollectionViewCell *cell = button.superView.superView;    NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];    NSString *title = self.strings[indexPath.row];    self.someLabel.text = title;}


Please try like this..

In YourCollectionViewCell.h

Create an IBOutlet not IBAction called button for the UIButton that you added to the xib. Remember you should connect the outlet to the cell object not to the file owner in the xib.

MainViewController.m

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{  cell.button.tag = indexPath.row;  [cell.button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];return cell;} -(void)buttonPressed:(UIButton*)sender{  NSLog(@"%d : %@",sender.tag,[array objectAtIndex:sender.tag]);  self.textLabel.text = [array objectAtIndex:sender.tag]; }

Edit- Handle multiple sections

 -(void)buttonPressed:(UIButton*)sender {  NSIndexPath  *indexPath = [self.collectionView indexPathForCell: (UICollectionViewCell *)sender.superview.superview];NSLog(@"Section : %d  Row: %d",indexPath.section,indexPath.row);if (0 == indexPath.section) {    self.textLabel.text = [firstArray objectAtIndex:indexPath.row];}else if(1 == indexPath.section){     self.textLabel.text = [secondArray objectAtIndex:indexPath.row];}}


When I edit the code in the UICollectionViewCell's action, I cannot access the array property.

That's because you connected the button action to the "wrong" object. It needs to be connected to the MainViewController (or whoever it is that does have access to the array property).

You are going to have several tasks to perform:

  • Receive the button action message.

  • Access the array (the model for the data).

  • Throw a switch saying which cell should now have its label showing.

  • Tell the collection view to reloadData, thus refreshing the cells.

All those tasks should most conveniently belong to one object. I am presuming that this is MainViewController (and thus I am presuming that MainViewController is the delegate/datasource of the collection view).