简体   繁体   English

如何在单击按钮上获取UITableviewcell(自定义单元格)值

[英]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. 我有一个UITableViewCell (自定义单元格),我在其中创建一些按钮和文本字段,并为按钮和文本字段分配标签。 But i couldn't get button title and textfield values on click on button. 但是我无法在点击按钮上获得按钮标题和文本字段值。

In cellForRowAtIndexPath 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'

I think you can directly access the btn and textField2 properties of your cell, once you get it from cellForRowAtIndexPath: . 我认为,一旦从cellForRowAtIndexPath:获取它,就可以直接访问单元格的btntextField2属性cellForRowAtIndexPath: Assuming you are creating and returning instance of CustomCell , just typecast it to CustomCell instead of UITableviewCell . 假设您正在创建并返回CustomCell实例,只需将其强制转换为CustomCell而不是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! 希望有所帮助!

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);

}

Following code to get indexPath by "event" param may be better: 以下代码通过“event”参数获取indexPath可能更好:

-(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:) submitBtn的目标选择器确认更改为@selector(submitBtnAction:event:)

Usually when you receive an unrecognized selector error it's because you are accessing an object that has been replaced in memory. 通常当您收到unrecognized selector错误时,这是​​因为您正在访问已在内存中替换的对象。 In your case it's probably that you are accessing a Cell that is not visible and so the contentview returns nil . 在您的情况下,您可能正在访问不可见的Cell,因此contentview返回nil

When you do your for loop you seem to access all cells which is not possible for not visible cells. 当你进行for循环时,你似乎访问了所有不可见的细胞。 For me you can only access visible cells orelse contentview is nil and therefore accessing titleLabel will give you the unrecognized selector error. 对我来说,你只能访问可见的单元格orelse contentview是nil,因此访问titleLabel会给你无法识别的选择器错误。

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. 否则,第一行标记为0且与内容视图标记匹配,默认情况下所有视图标记均为0。 Hence why you get the wrong view when tag is equal to 0. 因此,当tag等于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. 您已经通过cellForRowAtIndexPath:获得了特定的单元格cellForRowAtIndexPath:您只需要该单元格的按钮即可。

#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);

    }
}

问题是您使用标记0设置视图的子视图,而视图的标记属性默认值为0, [someview viewWithTag:0]返回someview本身。

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. 我传递一个函数来处理TableViewController中的事件作为TableViewcell的委托,并注册该事件以调用委托函数,并将其回调。 Here is how I did it 我就是这样做的

In the tableview controller cellForRow func 在tableview控制器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 在TableViewcell中,当用户单击按钮时,我会调用此委托

back in Tableviewcontroller, I would implement the delegate as follows 回到Tableviewcontroller,我将按如下方式实现委托

 @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 让我知道是否有更好的方法来做到这一点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM