8

I have added UIButton in UITableViewCells. I have when the user clicks the button we have get the indexpath to use the values from NSMutableArray. I have used the below to get the current IndexPath,

[getMeButton addTarget:self action:@selector(resendTheErrorMessage:) forControlEvents:UIControlEventTouchUpInside];

-(void) resendTheErrorMessage:(id)sender 
{
   NSLog(@"SEnder: %@", sender);
   //NSLog(@"Index Path : %@", indexpath);
}

Can anyone please help me to pass current indexpath UIButton's @selector. Thanks in advance.

EDIT:

This is the output I got from NSLog()

<UIButton: 0x864d420; frame = (225 31; 95 16); opaque = NO; tag = 105; layer = <CALayer: 0x864d570>>
Daniel
  • 23,129
  • 12
  • 109
  • 154
Yuvaraj.M
  • 9,741
  • 16
  • 71
  • 100
  • You can set tag to your buttons according to number of row of your cell then you can easily get the cellIndex. Show the code where you added your button on cell (cellForRowAtIndexPath:) method ? – TheTiger Aug 13 '12 at 14:16
  • @VakulSaini Thanks. I didn't get the cellIndex from (id)sender. I have edited my question please view this. Thanks. – Yuvaraj.M Aug 13 '12 at 14:20
  • You are getting this because you are printing the id of `UIButton`. See my post to get cellIndex – TheTiger Aug 13 '12 at 14:26
  • 1
    possible duplicate of [How to know the UITableview row number](http://stackoverflow.com/questions/9274494/how-to-know-the-uitableview-row-number) - tags are a poor solution to this in my opinion. – jrturton Aug 13 '12 at 14:38
  • @jrturton - Nice solution .... I have up voted you for this. Great! – TheTiger Aug 14 '12 at 07:04

5 Answers5

30

Add Your UIButton Like this

UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(10.0, 2.0, 140.0, 40.0)];
[btn setTitle:@"ButtonTitle" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn setTag:indexPath.row];
[cell.contentView addSubview:btn];

And then get its tag number -

-(void)buttonClicked:(id)sender
{
    NSLog(@"tag number is = %d",[sender tag]);
    //In this case the tag number of button will be same as your cellIndex.
   // You can make your cell from this.

   NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[sender tag] inSection:0];
   UITableViewCell *cell = [tblView cellForRowAtIndexPath:indexPath];
}

Note: Above solution will work when your tableView has only 1 section. If your tableView has more than one section either you should know your section index or go for below methods.

Alternative:1

UIView *contentView = (UIView *)[sender superview];
UITableViewCell *cell = (UITableViewCell *)[contentView superview];
NSIndexPath *indexPath = [tblView indexPathForCell:cell];

Alternative:2

CGPoint touchPoint = [sender convertPoint:CGPointZero toView:tblView];
NSIndexPath *indexPath = [tblView indexPathForRowAtPoint:touchPoint];
UITableViewCell *cell = [tblView cellForRowAtIndexPath:indexPath];
TheTiger
  • 13,264
  • 3
  • 57
  • 82
  • 1
    First one will not work because in this you will have to know section index .... but alternative solution will work...... – TheTiger May 06 '13 at 04:22
6

Given that the button is a subview of the cell view, and that the table view knows the index path of the cell view, something like this would work:

- (UITableViewCell *)containingCellForView:(UIView *)view
{
    if (!view.superview)
        return nil;

    if ([view.superview isKindOfClass:[UITableViewCell class]]) 
        return (UITableViewCell *)view.superview;

    return [self containingCellForView:view.superview];
}

- (IBAction)buttonClicked:(id)sender
{
    UITableViewCell *containingCell = [self containingCellForView:sender];
    if (containingCell) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:containingCell];
        NSLog(@"Section: %i Row: %i", indexPath.section, indexPath.row);
    }
}
Simon Lawrence
  • 564
  • 2
  • 8
  • This will work, but you have to make sure that the button is a *direct* subview of the table cell (which it usually will be). – sgress454 Aug 13 '12 at 15:53
  • And adding subView to direct cell.view is not good...! We add it on cell.contentView .... Well idea is good :-) – TheTiger Aug 14 '12 at 06:51
  • It is good if you're setting it to be the accessory view of the cell - the original question didn't specify where it was being added. Obviously if it's n levels down in a view hierarchy then you have to go n levels back up to get to the cell view. – Simon Lawrence Aug 14 '12 at 15:37
  • Exactly what I needed for multiple sections! Saved me lots of frustration thanks! – RyanG Jan 16 '13 at 18:56
  • Good solution and handles plain or grouped tableviews. – LJ Wilson Feb 24 '13 at 13:27
2

If you only need the table row, then you can set the button's tag property to the row number. If you need the whole path (with section number) then you'll have to subclass UIButton and make a new property ("indexPath" would be a good name) that you would set when you add the button to the table row.

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • I don't think this will work. AFAIK you can't pass your own parameters on a action:@selector? – Joshua Dance May 01 '13 at 17:54
  • Which part wouldn't work? No extra parameters would be required; the idea is to encode the index information in the button object itself at the time that it's added to the table, either via the tag property or a custom property of a subclass. The tag method is what's used in the accepted answer for this question. – sgress454 May 01 '13 at 20:56
2

For a tableview with more than one section a simpler solution would be to assign the tag:

cell.button.tag = indexPath.section * 1000 + indexPath.row

In the event handler use:

let section = sender.tag / 1000
let row = sender.tag % 1000

Note that you need to multiply with a larger number than 1000 if any of your sections can contain 1000 or more rows.

Peter Robert
  • 1,292
  • 11
  • 18
0

for me works if add tag to button in the cellForRowAtIndexPath...

cell.button.tag = indexPath.row;

and in the cell class get the tag... For example:

 NSLog(@"tag number is = %d",[sender tag]);

whit that you can know the cell.row. well this works for me, Sorry for my english.

indiefr
  • 59
  • 2