Arthur
Arthur

Reputation: 1760

Call function from UIButton in UICellView

I have UITableView with custom cells. On cell I have a buttons, and a method in my viewController (which contains UITableView)

My button click realisation is inside my myCustomCell class.

And the question is - What is the simplest way to call viewController method from myCustomCell?

I thought about delegates and NSNotificationCenter. But maybe there is another way.

EDIT

enter image description here

Upvotes: 1

Views: 80

Answers (2)

Chatar Veer Suthar
Chatar Veer Suthar

Reputation: 15639

Put following lines in your myCustomCell.h

@protocol ButtonTapDelegate

- (void) buttonDidTap:(UIButton*) button;

@end

@property (nonatomic, weak) NSObject<ButtonTapDelegate> *vs_delegate;

-(void) buttonIsPressed;

in your myCustomCell.m

@synthesize vs_delegate;

-(void) buttonIsPressed:(UIButton*)button {

    if([delegate conformsToProtocol:@protocol(ButtonTapDelegate)] && [delegate respondsToSelector:@selector(buttonDidTap:)]) {
       [vs_delegate buttonDidTap:button];
    }
}

In your viewController.h

myViewController : UIViewController <ButtonTapDelegate>

In your viewController.m, inside Method

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        [cell set.Vs_delegate:self];
        [cell.button setTag:indexPath.row];
        [cell.button addTarget:self action:@selector(buttonIsPressed) forControlEvents:UIControlEventTouchUpInside];
    [cell.button buttonIsPressed:indexPath.row];

Put following method inside ViewController.m

- (void) buttonDidTap:(UIButton*) button {
 // You have index, by Button's tag.
}

Upvotes: 3

rushisangani
rushisangani

Reputation: 3385

Most efficient and clean way to do this using blocks.

Declare a block property in your cell either TableViewCell or CollectionViewCell.

@property (nonatomic, copy) void(^buttonClickedAtIndexPath)(NSIndexPath *indexPath);

Declare button's action in Cell itself and Call above block in button click event.

-(IBAction)buttonClicked:(id)sender {

  // get indexPath here, which will be indexPath of cell.
  // you need to set button's tag as indexPath.row

  if(self.buttonClickedAtIndexPath) {
    self.buttonClickedAtIndexPath (indexPath);
  }
}

In your ViewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  TableViewCell *cell = // configure cell here.
  cell.button.tag = indexPath.row;
  cell.buttonClickedAtIndexPath = ^(NSIndexPath *indexPath){

   // you can do anything here. 
   // Call any method using self OR
   // perform segue

  }

}

If you've CollectionView inside TableViewCell then same things applies.

  • Make a class MyCollectionViewCell subclassing UICollectionViewCell.
  • Declare block property in MyCollectionViewCell.
  • Handle all the events in MyCollectionViewCell (including display data, delegate, datasource for collectionView).
  • Call a block from MyCollectionViewCell on button click.
  • Declare a property of MyCollectionViewCell in your TableViewCell.
  • In your controller's cellForRowAtIndexPath do something like this.

============================================================

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  TableViewCell *cell = // configure cell here.
  cell.mycollectionView.buttonClickedAtIndexPath = ^(NSIndexPath *indexPath){

   // you can do anything here. 
   // Call any method using self OR
   // perform segue

  }

}

Upvotes: 1

Related Questions