reloadData之后的indexPath.row错误

时间:2016-12-23 00:29:56

标签: ios objective-c uitableview

我正试图在tableView行中点击一个按钮的indexPath.row

当用户点击此按钮时,我得到了与该按钮对应的index.row,但是当我向源数组添加更多对象以通过调用reloadData来创建更多单元格时,{{1在每个单元格中,它不再向我提供正确的rowButtonClicked,例如我按下索引20,现在打印的indexPath.row为9。

indexPath.row中将事件添加到按钮:

cellForRowAtIndexPath

使用点击的索引执行某些操作:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

  lBtnWithAction = [[UIButton alloc] initWithFrame:CGRectMake(liLight1Xcord + 23, 10, liLight1Width + 5, liLight1Height + 25)];
  lBtnWithAction.tag = ROW_BUTTON_ACTION;
  lBtnWithAction.titleLabel.font = luiFontCheckmark;
  lBtnWithAction.tintColor = [UIColor blackColor];
  lBtnWithAction.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
            [cell.contentView addSubview:lBtnWithAction];
   }
 else 
     { 
       lBtnWithAction = (UIButton *)[cell.contentView viewWithTag:ROW_BUTTON_ACTION];
     }

//Set the tag
lBtnWithAction.tag = indexPath.row;
//Add the click event to the button inside a row
[lBtnWithAction addTarget:self action:@selector(rowButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

return cell;
}

Constants.h

-(void)rowButtonClicked:(UIButton*)sender
{
    //Get the index of the clicked button
    NSLog(@"%li", (long)sender.tag);
    [self doSomething:(long)sender.tag];

}

为什么在更改tableView的初始项时它给出的索引不正确?有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:3)

看起来你搞乱了按钮标签。设置标签后

lBtnWithAction.tag = indexPath.row;

您将无法使用

正确获取按钮
lBtnWithAction = (UIButton *)[cell.contentView viewWithTag:ROW_BUTTON_ACTION];

(假设ROW_BUTTON_ACTION是常数)。除非lBtnWithAction等于nil,否则indexPath.row将始终为ROW_BUTTON_ACTION

我建议继承UITableViewCell,在那里添加一个按钮属性,然后直接引用它而不是按标签搜索。在这种情况下,您将能够自由使用标签:) -

@interface UIMyTableViewCell : UITableViewCell
@property (nonatomic, strong, nonnull) UIButton *lBtnWithAction;
@end

然后在cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    UIMyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UIMyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        [cell.lBtnWithAction addTarget:self action:@selector(rowButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    }

    cell.lBtnWithAction.tag = indexPath.row;

    return cell;
}

答案 1 :(得分:1)

你可以简单地更新你的行 -

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]

答案 2 :(得分:0)

我对此的看法将是UITableViewCell的子类,并为其提供回复代理。

代码:

 //MyCoolTablewViewCell.h
 @protocol MyCoolProtocol<NSObject>
 -(void)youTouchedMyCoolCell:(MyCoolTableViewCell __nonnull *)myCoolCell;
 @end

 @interface MyCoolTableViewCell:UITableViewCell
 @property(nonatomic, weak,nullable) id<MyCoolProtocol>myCooldelegate; 
 @end

 //MyCoolTablewViewCell.m
 @interface MyCoolTableViewCell(){
    UIButton *mySuperCoolButton;
 }
 @end
 @implementation MyCoolTablewViewCell

 -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{

  if(!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])){
    return nil;
 }

 // init your stuff here
 // init button
 mySuperCoolButton = [UIBUtton buttonWithType:UIButtonTypeCustom]; 
 [mySuperCoolButton addTarget:self action:@selector(tappedMyCoolButton:) forControlEvents:UIControlEventTouchUpInside];
 return self;
 }

- (void)tappedMyCoolButton:(id)sender{
  if([_myCoolDelegate respondToSelector:@selector(youTouchedMyCoolCell:)]){
     [_myCoolDelegate youTouchedMyCoolCell:self];
  }
 }
 @end

然后在您的控制器中

// whatEverController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   // get the cell
    cell = [tableView dequeueReusableCellWithIdentifier:@"myCoolIdentifier"forIndexPath:indexPath];
cell.myCooldelegate = self;
}

-(void)youTouchedMyCoolCell:(MyCoolTableViewCell *)myCoolCell{
    NSIndexPath *myCoolIndexPath = [_tableView indexPathForCell:myCoolCell];
  // then do whatever you want with the index path
}