user1831389
user1831389

Reputation: 201

How to get UITableviewcell(custom cell) values on click on button

I have a UITableViewCell(Custom cell) in which i am creating some buttons and textfields and assigning tags to the buttons and textfields. But i couldn't get button title and textfield values on click on button.

In cellForRowAtIndexPath

`[((CustomCell *) cell).btn setTag:rowTag];
 [((CustomCell *) cell).textField2 setTag:rowTag+1];`

-(IBAction)submitBtnAction:(UIControl *)sender
{
    for (int i=0; i<[self->_dataArray count]; i++)
    {
        NSIndexPath *myIP = [NSIndexPath indexPathForRow:i inSection:0];
        NSLog(@"myIP.row %d",myIP.row);
        UITableViewCell *cell = [tblView1 cellForRowAtIndexPath:myIP];
        NSLog(@"tag %d",cell.tag);
        UIButton *btn = (UIButton *)[cell.contentView viewWithTag:i];
        NSLog(@"btn text %@, tag %d",btn.titleLabel.text,btn.tag);
        UITextField *tf = (UITextField *)[cell.contentView viewWithTag:i+1];
        NSLog(@"tf text %@, tag %d",tf.text,btn.tag);

    }
}

I'm getting error like this

-[UITableViewCellContentView titleLabel]: unrecognized selector sent to instance 0x71844e0
2013-07-17 13:48:29.998 Text[1271:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCellContentView titleLabel]: unrecognized selector sent to instance 0x71844e0'

Upvotes: 5

Views: 12580

Answers (7)

A B Vijay Kumar
A B Vijay Kumar

Reputation: 869

The way I would do this is. I pass a function to handle the event in TableViewController as a delegate to TableViewcell, and register the event to call the delegate function, and call it back. Here is how I did it

In the tableview controller cellForRow func

        let cell = tableView.dequeueReusableCell(withIdentifier: "blablabla") as! FeedbackTableViewCell
        cell.buttonEventDelgate = buttonPressed
        cell.indexPath = indexPath //This is required to find which cell button was pressed
        return cell

In the TableViewcell, when the user clicks the button, I call this delegate

back in Tableviewcontroller, I would implement the delegate as follows

 @objc func buttonPressed(sender: UIButton, indexPath: IndexPath) -> Void {
    print("button pressed \(indexPath.row)")
  }

Hope this helps!!! let me know if there are better ways of doing this

Upvotes: 0

simalone
simalone

Reputation: 2768

Following code to get indexPath by "event" param may be better:

-(IBAction)submitBtnAction:(UIControl *)sender event:(id)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchPos = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView  indexPathForRowAtPoint:touchPos];
    if(indexPath != nil)
    {
       //Todo: get model at indexPath, update cell or something other 
    }
}

submitBtn's target selector confirm change to @selector(submitBtnAction:event:)

Upvotes: 1

tassar
tassar

Reputation: 588

The problem is you set your view's subview with tag 0, while view's tag property default value is 0, and [someview viewWithTag:0] return someview itself.

Upvotes: 0

Amar
Amar

Reputation: 13222

I think you can directly access the btn and textField2 properties of your cell, once you get it from cellForRowAtIndexPath:. Assuming you are creating and returning instance of CustomCell, just typecast it to CustomCell instead of UITableviewCell. See modified code below

-(IBAction)submitBtnAction:(UIControl *)sender
{
        UIButton *button = (UIButton*)sender;
        NSIndexPath *myIP = [NSIndexPath indexPathForRow:sender.tag inSection:0];
        //Type cast it to CustomCell
        CustomCell *cell = (CustomCell*)[tblView1 cellForRowAtIndexPath:myIP];
        UIButton *btn = cell.btn;
        NSLog(@"btn text %@, tag %d",btn.titleLabel.text,btn.tag);

        UITextField *tf = cell.textField2;
        NSLog(@"tf text %@, tag %d",tf.text,btn.tag);
}

Hope that helps!

Upvotes: 11

Satheesh
Satheesh

Reputation: 11276

Simple way to do it:

-(IBAction)submitBtnAction:(UIControl *)sender
{
   UIButton *senderButton = (UIButton *)sender;

    NSIndexPath *myIP = [NSIndexPath indexPathForRow:i inSection:0];

    CustomCell *cell = (CustomCell*)[tblView1 cellForRowAtIndexPath:myIP];

    NSLog(@"cell.textField -tag :%d",cell.textField2.tag);

    NSLog(@"cell.btn -tag :%d",cell.btn.tag);

}

Upvotes: 2

HpTerm
HpTerm

Reputation: 8281

Usually when you receive an unrecognized selector error it's because you are accessing an object that has been replaced in memory. In your case it's probably that you are accessing a Cell that is not visible and so the contentview returns nil.

When you do your for loop you seem to access all cells which is not possible for not visible cells. For me you can only access visible cells orelse contentview is nil and therefore accessing titleLabel will give you the unrecognized selector error.

Upvotes: 0

Conor
Conor

Reputation: 1777

Add a padding to the tag value. Otherwise the first row tag is 0 and that matches the content view tag, all view tags are 0 by default. Hence why you get the wrong view when tag is equal to 0.

#define PADDING 100
[((CustomCell *) cell).btn setTag:PADDING + rowTag];
[((CustomCell *) cell).textField2 setTag:PADDING + rowTag+1];

However I would change the solution to simply not use an incremental tag but a static tag. You already have the specific cell via cellForRowAtIndexPath: all you need are the buttons of that cell.

#define BUTTON_TAG 10
#define TEXT_TAG 11

cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
if (cell == nil) {
    cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CustomCell"] autorelease];
    [((CustomCell *) cell).btn setTag:BUTTON_TAG];
    [((CustomCell *) cell).textField2 setTag:TEXT_TAG];
}

-(IBAction)submitBtnAction:(UIControl *)sender
{
    for (int i=0; i<[self->_dataArray count]; i++)
    {
        NSIndexPath *myIP = [NSIndexPath indexPathForRow:i inSection:0];
        NSLog(@"myIP.row %d",myIP.row);
        UITableViewCell *cell = [tblView1 cellForRowAtIndexPath:myIP];
        UIButton *btn = (UIButton *)[cell.contentView viewWithTag:BUTTON_TAG];
        NSLog(@"btn text %@, tag %d",btn.titleLabel.text,btn.tag);
        UITextField *tf = (UITextField *)[cell.contentView viewWithTag:TEXT_TAG];
        NSLog(@"tf text %@, tag %d",tf.text,btn.tag);

    }
}

Upvotes: 0

Related Questions