title: Objective c - Best practice to handle a button touch event for a button of a custom UITableViewCell
body: <p>What is best practice to handle a button touch event for a button of a custom <code>UITableViewCell</code>?  </p>
  
  <p>my classes:
  <code>MyViewController</code>, <code>MyCustomCell</code></p>
  
  <p>I can think of three options: </p>
  
  <p><strong>First option-</strong> Have the button as a property of <code>MyCustomCell</code>, and then add a target to it in the <code>MyViewController</code> .m file with <code>MyViewController</code> as the target.</p>
  
  <p><code>MyViewController</code> .m file</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *CellIdentifier = @"customCell";
  
      MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
      cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  
      [cell.theButton addTarget:self
                         action:@selector(theButtonTapped:)
               forControlEvents:UIControlEventTouchUpInside];
      }
  
      // Configure the cell...    
      [self configureCell:cell atIndexPath:indexPath];
  
      return cell;
  }
  
  - (void)theButtonTapped:(UIButton *)sender
  {
      MyCustomCell *selectedCell = (MyCustomCell *)sender.superview;
  
      if (selectedCell) {
          NSIndexPath *indexPath = [self.tableView indexPathForCell:selectedCell];
          MyModel *selectedModel = [self.model objectAtIndex:indexPath.row]; 
  
          // do something with the model...
      }
  }
  </code></pre>
  
  <p><strong>Second option-</strong> If the custom cell was made in IB, Set the nib File's Owner to be <code>MyViewController</code>, implement <code>buttonTapped:</code> method in <code>MyViewController</code> and connect the button's Touch Up Inside event to the <code>buttonTapped:</code> method.</p>
  
  <p><strong>Third option-</strong> if the custom cell wasn't made in IB, add a target to the button in the <code>MyCustomCell</code> .m file with <code>MyCustomCell</code> as the target.<br>
  Define a <code>MyCustomCellDelegate</code> add <code>@property (nonatomic, assign) id&lt;MyCustomCellDelegate&gt; delegate</code> to <code>MyCustomCell</code> and call this delegate when button tapped.<br>
  Set <code>MyViewController</code> as the cell's delegate when creating cells and implement the <code>MyCustomCellDelegate</code> protocol.</p>
  
  <p><code>MyCustomCell</code> .h file </p>
  
  <pre><code>@class MyCustomCell;  
  
  @protocol MyCustomCellDelegate &lt;NSObject&gt;
  - (void)buttonTappedOnCell:(MyCustomCell *)cell;
  @end
  
  @interface MyCustomCell : UITableViewCell
  
  @property (nonatomic, retain) UIButton *theButton;
  @property (nonatomic, assign) id&lt;MyCustomCellDelegate&gt; delegate;
  
  @end
  </code></pre>
  
  <p><code>MyCustomCell</code> .m file  </p>
  
  <pre><code>- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
  {
      self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
      if (self) {
          // Initialization code
          self.theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
          self.theButton.frame = CGRectMake(10,10,50,30);
          [self addSubview:self.theButton];
  
          [self.theButton addTarget:self
                             action:@selector(theButtonTapped:)
                   forControlEvents:UIControlEventTouchUpInside];
      }
      return self;
  }
  
  - (void)theButtonTapped:(UIButton *)sender
  {
      [self.delegate buttonTappedOnCell:self];
  }
  </code></pre>
  
  <p><code>MyViewController</code> .m file</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *CellIdentifier = @"customCell";
  
      MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
          cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  
          cell.delegate = self;
      }
  
      // Configure the cell...    
      [self configureCell:cell atIndexPath:indexPath];
  
      return cell;
  }
  
  - (void)buttonTappedOnCell:(MyCustomCell *)selectedCell
  {
      if (selectedCell) {
          NSIndexPath *indexPath = [self.tableView indexPathForCell:selectedCell];
          MyModel *selectedModel = [self.model objectAtIndex:indexPath.row];
  
          // do something with the model...
      }
  }
  </code></pre>