Reputation: 201
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
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
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
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
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
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
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
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