CellForRowAtIndexPath 中给出的 UIButton 标记仅给出自定义 UITableViewCell 中的最后一个标记值

Posted

技术标签:

【中文标题】CellForRowAtIndexPath 中给出的 UIButton 标记仅给出自定义 UITableViewCell 中的最后一个标记值【英文标题】:UIButton tag given in CellForRowAtIndexPath gives only last tag value in Custom UITableViewCell 【发布时间】:2017-01-24 06:27:56 【问题描述】:

我在UITableViewCell 子类中有两个UIButton,在视图控制器类中我有它的选择器方法,但是在单击按钮时,它总是给出在cellForRowAtIndexPath 方法中分配的最后一个标记值。

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

    static NSString *CellIdentifier = @"cell";

    customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    customCell.oneYear.tag = indexPath.row;

    customCell.threeYearButton.tag = indexPath.row + 50;
[customCell.oneYear addTarget:self
                    action:@selector(oneYearButtonAction)
          forControlEvents:UIControlEventTouchUpInside];

[customCell.threeYearButton addTarget:self
                       action:@selector(threeYearButtonAction)
             forControlEvents:UIControlEventTouchUpInside];

[customCell setSelectionStyle:UITableViewCellSelectionStyleNone];

如果我使用 IBAction 效果很好,但我必须使用选择器方法,这会出现上述问题。

请帮助。

【问题讨论】:

您能否添加您的cellForRowAtIndexPath 方法,以便我们了解您是如何设置按钮标签的? 是的,这里也一样。请添加您的代码的 sn-p 如果我在 didselectRow 方法中执行,选择器方法会执行而不是 didselectrow,所以它不起作用 它应该给我不同行中不同按钮的不同标签值 用这个检查出队单元格 - dequeueReusableCellWithIdentifier:forIndexPath: 【参考方案1】:

您需要使用 cellForRowAtIndexPath 创建自定义类的新实例,而不是使用相同的实例 customCell

改为:

customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

您需要像这样创建新对象:

CustomCellName *customCell = (CustomCellName*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

编辑:您可以尝试这样,而不是使用tag 与您的单元格的按钮操作。

-(void)oneYearButtonAction:(UIButton*)sender 
     CGPoint center= sender.center; 
     CGPoint rootViewPoint = [sender.superview convertPoint:center toView:self.tableView];
     NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rootViewPoint];
     CustomCellName *currentCell = [self.tableView cellForRowAtIndexPath:indexPath];

【讨论】:

我有一个问题,稍后我在选择器方法中从哪里获取 customCell 对象,您是否建议创建多个对象? 请死池 我现在要问一些愚蠢的事情,我如何从选择器方法中调用这个方法? 在我的问题中,我正在调用一个方法“@selector(oneYearButtonAction)” 现在您已经添加了一个参数发送者,我该如何调用它 @ios_Dev 将您的选择器更改为action:@selector(oneYearButtonAction:) 就像threeYearButtonAction 一样【参考方案2】:

您已经在cellForRow 方法之外声明了单元格。如果你这样做,你的单元格对象将包含最后一个对象,这就是你的按钮总是有最后一个标签的原因。

解决方案

cellForRow 中为这样的单元格声明您的对象

  MyCustomCell *customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //what ever your class name be I am says MyCustomCell.

注意:如果您想在任何其他方法中使用单元格对象,那么将有很多其他属性可用。

如何在按钮操作方法中获取单元格对象

- (IBAction)btnShowClicked:(UIButton*)sender 

CGPoint buttonPosition = [sender convertPoint:CGPointZero tblObject];
NSIndexPath *indexPath = [tblObject indexPathForRowAtPoint:buttonPosition];

MyCustomCell *customCell = [tblObject cellForRowAtIndexPath:indexPath];

【讨论】:

好的,Dahiya 先生,让我试试吧,顺便说一句,你是来自 susana、sisana 等的吗,哈哈?大多数 dahiya 都来自那里 @ios_Dev hehehe 我已经犯了同样的错误,这就是为什么我知道你到底发生了什么。 请解释一下您的注意事项:是的,我想在其他方法中使用它的对象 @ios_Dev 我把答案写在那里,你只需要在按钮操作中写下这些行,别无他法。【参考方案3】:

我知道您已经解决了这个问题。仍在为可能需要完整代码的人发布。仅供参考,您可以对两个按钮使用相同的方法,您可以直接在该方法中检查哪个按钮被btn.tag 单击,因为按钮对象已经传递。

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
        customTableCell *customCell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

        [customCell.btn1 setTitle:[NSString stringWithFormat:@"Button %ld",(long)indexPath.row]
     forState:UIControlStateNormal];
        [customCell.btn2 setTitle:[NSString stringWithFormat:@"Button %ld",(long)indexPath.row+10]
                         forState:UIControlStateNormal];
        [customCell.btn1 setTag:indexPath.row];
        [customCell.btn2 setTag:indexPath.row+10];

        [customCell.btn1 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [customCell.btn2 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
        return customCell;
    
    -(void) btnClicked:(UIButton *) btn 
        UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"" message:[NSString stringWithFormat:@"Button %ld tapped",(long)btn.tag] preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
        [alertC addAction:action];
        [self presentViewController:alertC animated:true completion:nil];
    

    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
        return 1;
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
        return 5;
    

【讨论】:

【参考方案4】:

我已经在 cellForRowAtIndexPath 中创建了这个重做按钮

btnper = [UIButton buttonWithType:UIButtonTypeCustom];
btnper.frame = CGRectMake(10, 10, 50, 30);
btnper.tag = indexPath.row;
btnper.titleLabel.font = [UIFont systemFontOfSize:13.0f];
[btnper setImage:[UIImage imageNamed:@"Radiooff1"]
        forState:UIControlStateNormal];
[btnper setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnper setTitle:@" 0%" forState:UIControlStateNormal];
[btnper addTarget:self action:@selector(btnperPress:)   
        forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:btnper];

这是我的操作方法,用于识别按下了哪个单元格按钮

- (IBAction)btnperPress:(UIButton *)sender 
    NSInteger selectedCheckBox = sender.tag; 
    NSLog (@"%d",selectedCheckBox);

【讨论】:

不是一个合适的解决方案,因为每次创建新单元时都会创建新按钮。

以上是关于CellForRowAtIndexPath 中给出的 UIButton 标记仅给出自定义 UITableViewCell 中的最后一个标记值的主要内容,如果未能解决你的问题,请参考以下文章

从 cellForRowAtIndexPath 中调用 heightForRowAtIndexPath?

nib 项目中的 CellForRowAtIndexPath

为啥我的 NSMutableArray 在 cellForRowAtIndexPath 中“半死”?

在 cellForRowAtIndexPath 中获取 iOS CoreData 后台线程

UIView 在 cellForRowAtIndexPath 中重叠/再次创建

无法在 cellForRowAtIndexPath 中获取单元格框架或约束