James V
James V

Reputation: 189

Getting a button press from a custom UITableViewCell's button

I have a project with a custom UITableViewCell (cell.h/.m/.xib) that has 2 labels (labelMain/labelSub), and 2 buttons on it (buttonName/buttonInfo) linked to 2 actions (showName/showInfo).

What I want to do is be able to access the 2 actions in my projects main viewcontroller so that when showName is pressed, a textfield.text in the viewcontroller (not in the cell) is set to that specific cell's labelMain.text.

Hope that makes sense. My problem is that if I write the action (showName) in the cell.m, I cannot access the textfield from my main viewcontroller. On the flip side, if I write the action in my viewcontroller, how do I know which button inside which cell was tapped?

Hope this makes sense...

Upvotes: 9

Views: 11284

Answers (5)

Tib
Tib

Reputation: 1280

The simplest solution in my opinion:

In your CustomCell.h :

@property (nonatomic, copy) void (^buttonTapAction)(id sender);

In your CustomCell.m create the IBAction and connect it to your UIButton :

-(IBAction)cellButtonIsPressed:(id)sender{

    if (self.buttonTapAction) {
        self.buttonTapAction(sender);
    }
}

Then in the ViewController.m where your UITableView is managed :

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

        static NSString* cellIdentifier = @"customCell";
        CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        cell.buttonTapAction = ^(id sender){
                //Do what you want to do when the button inside THIS cell is clicked
            };
    }

Upvotes: 1

Ajith Kumar
Ajith Kumar

Reputation: 1223

I suggest to use delegate(protocol) method for this. You will be having full control on the button, cell and the view controller. And its very simple too

Upvotes: 1

Sanket Pandya
Sanket Pandya

Reputation: 1095

Try to create the button dynamically, with its methods in same controller. Do this in cellForRowAtIndexPath: method:

if (cell == nil) 
{ 
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"WorkRequestedCC" owner:self options:nil];
    {
        for (id oneObject in nib) if ([oneObject isKindOfClass:[WorkRequestedCC class]])
            cell = (WorkRequestedCC *)oneObject;

    }
    UILabel *costLbl=[[UILabel alloc]initWithFrame:CGRectMake(792, 13, 10, 15)];
    costLbl.text=@"$";
    [costLbl setBackgroundColor:[UIColor clearColor]];
    UITextField *txtCost=[[UITextField alloc]initWithFrame:CGRectMake(805, 10, 94, 27)];
    txtCost.backgroundColor=[UIColor whiteColor];
    [txtCost setKeyboardType:UIKeyboardTypeNumberPad];
    txtCost.text=obj.expCost;

    [txtCost addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];
    [cell.contentView addSubview:costLbl];
    [cell.contentView addSubview:txtCost];

    cell.lblDes.text=obj.expDes;

}

- (void)textChanged
{
     //your code here
}

Upvotes: 0

HelmiB
HelmiB

Reputation: 12333

Use tag can identify which button in which cell is being tapped.

- (UITableViewCell *)tableView:(UITableView *)tableViews cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      //init identifier
      if (cell ==nil)
       {
        //load nib file
       }
    
      buttonName.tag = indexPath.row;
      [buttonName addTarget:self action:@selector(showName:) forControlEvents:UIControlEventTouchUpInside];

      buttonInfo.tag = indexPath.row;
      [buttonInfo addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];

    }
}

-(void) showName:(UIButton*)button{
  int row = button.tag; //you know that which row button is tapped
}

-(void)showInfo:(UIButton*)button{
 int row = button.tag;//you know that which row button is tapped
}

---------------- EDIT -------------

If you need to know which button is pressed based on row & section, you may try this below. (in cellForRowAtIndexPath: method)

int tag = (indexPath.row+1)+(indexPath.section*100);
buttonName.tag = tag;

When button at

row = 5, section = 0 then tag = 6.

row = 4, section = 3 then tag = 305.

row = 0, section = 11 then tag =1101.

limitation, row cannot be more than 99. and DON'T use positive tag for other view. if you need use tag, try negative. (-1, -9, -100).

so from here, you can calculate back row & section of indexPath. using this :

-(NSIndexPath*)getIndexPathFromTag:(NSInteger)tag{
    /* To get indexPath from textfeidl tag,
     TextField tag set = (indexPath.row +1) + (indexPath.section*100) */
    int row =0;
    int section =0;
    for (int i =100; i<tag; i=i+100) {
        section++;
    }
    row = tag - (section*100);
    row-=1;
    return  [NSIndexPath indexPathForRow:row inSection:section];
    
}

how to use :

-(void)showInfo:(UIButton*)button{
     NSIndexPath *indexPath = [self getIndexPathFromTag:button.tag];
     int row = indexPath.row;
     int section = indexPath.section;
}

Upvotes: 16

hchouhan02
hchouhan02

Reputation: 946

Try this in viewController.m file in cellForRowAtIndexPath method

[[customCell showNameBtn] setTag:indexPath.row];
[[customCell showNameBtn] addTarget:self action:@selector(showName:) forControlEvents:UIControlEventTouchDown];

-(void) showName:(id)sender
{
// check here the sender tag and then perform you action what you want.
}

Upvotes: 3

Related Questions