Get the UITableViewCell indexPath using custom cells

10,621

Solution 1

since u are using the custom cell i think u need to handle selection also, because u are touching the button inside the custom cell not the cell itself therefore tableview delegate methods are not fired, better as i said in ur custom cell put a delegate method for example in ur custom cells

in your CellTypeOne.h add this

//@class CellTypeOne; //if u want t pass cell to controller
@protocol TouchDelegateForCell1 <NSObject> //this delegate is fired each time you clicked the cell
 - (void)touchedTheCell:(UIButton *)button;
 //- (void) touchedTheCell:(CellTypeOne *)cell; //if u want t send entire cell this may give error add `@class CellTypeOne;` at the beginning  
@end

@interface CellTypeOne : UITableViewCell
{

}
@property(nonatomic, assign)id<TouchDelegateForCell1> delegate; //defining the delegate
- (IBAction)actionForFirstButton:(id)sender;
- (IBAction)actionForSecondButton:(id)sender;
- (IBAction)actionForThirdButton:(id)sender;
- (IBAction)actionForFourthButton:(id)sender;

in your CellTypeOne.m file

@synthesize delegate; //synthesize the delegate 

- (IBAction)actionForFirstButton:(UIButton *)sender 
{ 
   //add this condition to all the actions becz u need to get the index path of tapped cell contains the button
    if([self.delegate respondsToSelector:@selector(touchedTheCell:)])
     {
        [self.delegate touchedTheCell:sender];
        //or u can send the whole cell itself
        //for example for passing the cell itself
        //[self.delegate touchedTheCell:self]; //while at the defining the delegate u must change the sender type to - (void)touchedTheCell:(CellTypeOne *)myCell; if it shows any error  in the defining of the delegate add "@class CellTypeOne;" above the defying the delegate
    }
}

and in your ViewContainingMyTableView.h

 @interface ViewContainingMyTableView : UIViewController <UITableViewDelegate, UITableViewDataSource ,TouchDelegateForCell1> //confirms to custom delegate like table  delegates
 {
    UITableView *myTBV;
 }

 @property (retain, nonatomic) IBOutlet UITableView *myTBV;

 @end

and in the ViewContainingMyTableView.m file

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{  
   //during the creating the custom cell 
   CellTypeOne *cell1 = [self.aTableView dequeueReusableCellWithIdentifier:@"cell"];
   if(cell1 == nil)
   { 
     cell1 = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
   }
     cell.delegate = self; //should set the delegate to self otherwise delegate methods does not called this step is important
}

//now implement the delegate method , in this method u can get the indexpath of selected cell 

- (void)touchedTheCell:(UIButton *)button
 {
    NSIndexPath *indexPath = [self.aTableView indexPathForCell:(UITableViewCell *)button.superview];
    NSLog(@"%@",indexPath.description);

 }
 /* if u pass the cell itself then the delegate method would be like below
- (void)touchedTheCell:(CellTypeOne *)myCell
 {
    NSIndexPath *indexPath = [self.aTableView indexPathForCell:myCell];//directly get the cell's index path
    //now by using the tag or properties, whatever u can access the contents of the cell
    UIButton *myButton = [myCell.contentView viewWithTag:1000]; //get the button 
    //... u can access all the contents in cell 
 }
 */

in your case, this is for first button in the cell, add the delegate methods for each buttons having different functions, repeat above procedure for another buttons in the cell

hope u get this :) hapy coding

Solution 2

With iOS7 you can get it like this :

- (IBAction)actionForTheUniqueButton:(id)sender
{
    YouCellClass *clickedCell = (YouCellClass*)[[sender superview] superview];
    NSIndexPath *indexPathCell = [self.tableView indexPathForCell:clickedCell];
}
Share:
10,621
Jonathan F.
Author by

Jonathan F.

Updated on June 04, 2022

Comments

  • Jonathan F.
    Jonathan F. about 2 years

    I have a view which contain a UITableView. The cells of this UITableView are created in Interface Builder, in order to have different kinds of cells. So the action of each button is managed in the cell classes like following.

    - My UITableView containing different kinds of cells :

    enter image description here

    - The header file of my class for type one cells ("CellTypeOne.h") :

    @interface CellTypeOne : UITableViewCell
    {
    }
    
    - (IBAction)actionForFirstButton:(id)sender;
    - (IBAction)actionForSecondButton:(id)sender;
    - (IBAction)actionForThirdButton:(id)sender;
    - (IBAction)actionForFourthButton:(id)sender;
    

    - The header file of my class for type two cells ("CellTypeTwo.h") :

    @interface CellTypeTwo : UITableViewCell
    {
    }
    
    - (IBAction)actionForTheUniqueButton:(id)sender;
    

    - The view which contain my table view ("ViewContainingMyTableView.h") :

    @interface ViewContainingMyTableView : UIViewController <UITableViewDelegate, UITableViewDataSource>
    {
        UITableView *myTBV;
    }
    
    @property (retain, nonatomic) IBOutlet UITableView *myTBV;
    
    @end
    

    Here the thing I want to do :

    When I click on the first button in the first cell, for example, I want to be able to show the indexPath of the "current" cell.

    For example, I want to have the following output when :

    • I click on the first button in the first cell : 0
    • I click on the third button in the first cell : 0
    • I click on the first and unique button in the second cell : 1
    • etc...
  • Jonathan F.
    Jonathan F. over 10 years
    When I click on a button, the cell is not in a selected state... That's my problem !
  • Jonathan F.
    Jonathan F. over 10 years
    Hum, how can I refer to my tableView ? Because it's in an other view, so self.myTableView does not work...
  • Jonathan F.
    Jonathan F. over 10 years
    Cells are dynamically generated... I prefer to do not use the tags.
  • Jonathan F.
    Jonathan F. over 10 years
    I don't want to use the tags... Sorry
  • Jonathan F.
    Jonathan F. over 10 years
    It may work but I don't know how to refer to my tableView.I try this but it does not work : ViewContainingMyTableView *v = [[ViewContainingMyTableView alloc] init]; NSLog(@"myTBV : %@", [p myTBV]);
  • Jonathan F.
    Jonathan F. over 10 years
    I pass into touchedTheCell, so it's a good thing. But [self.tbvTimeLine indexPathForCell:(UITableViewCell *)button.superview]is null...
  • Jonathan F.
    Jonathan F. over 10 years
    self.myTBV is not null, and button.superview too. So what can be the issue ?
  • Shankar BS
    Shankar BS over 10 years
    check what u are passing cell or button
  • Jonathan F.
    Jonathan F. over 10 years
    Hum... I don't know what to do :( button.superview is equal to <UITableViewCellContentView: 0xa56e8a0; frame = (0 0; 320 110); opaque = NO; gestureRecognizers = <NSArray: 0xa56e9f0>; layer = <CALayer: 0xa56e910>>, and (UITableViewCell *)button.superview too...
  • Shankar BS
    Shankar BS over 10 years
  • zbMax
    zbMax over 10 years
    In fact... The first thing I think you can do (and because you have created your own class for cells) is to add a property in your customized cells referring to the table View displaying the cell. This solution is suggested for this question : stackoverflow.com/questions/1110482/…