TableView单元格重用导致按钮标题在滚动时更改

时间:2015-06-22 05:39:40

标签: ios uitableview uibutton reuseidentifier

我有一个显示名称的列表和一个标题为&#34的按钮;关注"。当我点击按钮标题时,应更改为" UnFollow"。如果我再次点击该按钮,标题应再次更改为"关注"。这工作正常,但是当我滚动表格时,由于单元格重用,其他单元格的标题也在变化。

代码如下:

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

    static NSString *CellIdentifier = @"AuthorsListCell";
    AuthorsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
                                                                     forIndexPath:indexPath];
    dic_eachAuthor = [[_arr_authors objectAtIndex:indexPath.row] mutableCopy];

    cell.lbl_authorName.text = [dic_eachAuthor objectForKey:@"name"];
    cell.btn_followOrUnfollow.tag = indexPath.row;

    if([dic_eachAuthor valueForKey:@"follow"]){
        [cell.btn_followOrUnfollow setTitle:@"UnFollow" forState:UIControlStateNormal];
    }
    else{

        [cell.btn_followOrUnfollow setTitle:@"Follow" forState:UIControlStateNormal];
    }

    // action button method declarations
    [cell.btn_followOrUnfollow addTarget:self action:@selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}


    -(void)followOrUnfollow:(UIButton *)sender
{
    if ([sender.titleLabel.text isEqualToString:@"Follow"]) {
        [sender setTitle:@"UnFollow" forState:UIControlStateNormal];
        [dic_eachAuthor setValue:@"1" forKey:@"follow"];

    }
    else if ([sender.titleLabel.text isEqualToString:@"UnFollow"]) {
        [sender setTitle:@"Follow" forState:UIControlStateNormal];
        [dic_eachAuthor setValue:nil forKey:@"follow"];


    }


}

请提出建议以防止细胞重复使用。

5 个答案:

答案 0 :(得分:1)

在cellForRowAtIndexPath中的followOrUnfollow中添加此条件

if ([sender.titleLabel.text isEqualToString:@"Follow"]) {
        [sender setTitle:@"UnFollow" forState:UIControlStateNormal];

    }
    else if ([sender.titleLabel.text isEqualToString:@"UnFollow"]) {
        [sender setTitle:@"Follow" forState:UIControlStateNormal];


    }

答案 1 :(得分:0)

在数据源中存储follow / unfollow状态信息。

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

    static NSString *CellIdentifier = @"CellIdentifier";
    ListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
                                                                     forIndexPath:indexPath];

    cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:@"name"];
    cell.btn_followOrUnfollow.tag = indexPath.row;

    // action button method declarations
    [cell.btn_followOrUnfollow addTarget:self action:@selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];

    NSString *btnTitle = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:@"userFollowUnfollow"];
     [sender setTitle:btnTitle forState:UIControlStateNormal];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

-(void)followOrUnfollow:(UIButton *)sender
{
    if ([sender.titleLabel.text isEqualToString:@"Follow"]) {
        [sender setTitle:@"UnFollow" forState:UIControlStateNormal];

    }
    else if ([sender.titleLabel.text isEqualToString:@"UnFollow"]) {
        [sender setTitle:@"Follow" forState:UIControlStateNormal];
    }

    [[_arr_authors objectAtIndex:sender.tag]  setValue:sender.titleLabel.text forKey:@"userFollowUnfollow"];

}

答案 2 :(得分:0)

当您最初填充表格行时,可以从此处的数组cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:@"name"];执行此操作。问题是您没有填充此数组中的follow或unfollow信息。因此,您所做的只是切换按钮,并且不会保存该按钮的状态。您需要做的是修改数组以保存follow / unfollow状态。然后从此数组填充表格单元格中的状态。然后当你调用followOrUnfollow:时,你需要修改数组中的状态。

当单元格被重用时,它会检查原始数组以填充它,填充数组中的follow,然后设置。

编辑添加一些代码:

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

    static NSString *CellIdentifier = @"CellIdentifier";
    ListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier                                                                     forIndexPath:indexPath];

    cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:@"name"];
    cell.btn_followOrUnfollow.tag = indexPath.row;
    if([[_arr_authors objectAtIndex:indexPath.row] valueForKey:@"follow"]){
          [cell.btn_followOrUnfollow setTitle:@"UnFollow" forState:UIControlStateNormal];
    else{
         [cell.btn_followOrUnfollow setTitle:@"Follow" forState:UIControlStateNormal];
    }

    // action button method declarations
    [cell.btn_followOrUnfollow addTarget:self action:@selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

-(void)followOrUnfollow:(UIButton *)sender
{
    if ([sender.titleLabel.text isEqualToString:@"Follow"]) {
        [sender setTitle:@"UnFollow" forState:UIControlStateNormal];
        [[_arr_authors objectAtIndex:sender.tag] setValue:1 forKey:@"follow"]
    }
    else if ([sender.titleLabel.text isEqualToString:@"UnFollow"]) {
        [sender setTitle:@"Follow" forState:UIControlStateNormal];
        [[_arr_authors objectAtIndex:sender.tag] setValue:0 forKey:@"follow"]
    }
}

我不在我的普通机器上,因此语法可能已关闭,但您应该明白这一点。另请注意,您必须将follow属性添加到_arr_authors

答案 3 :(得分:0)

你在这里遗漏了一些东西,试试这个:

-(void)followOrUnfollow:(UIButton *)sender
{
    NSDictionary *dict = (NSDictionary *) _arr_authors[sender tag];
    if ([[dict objectForKey:@"name"] isEqualToString:@"Follow"]) 
     {
        [sender setTitle:@"UnFollow" forState:UIControlStateNormal];

     }
     else if ([[dict objectForKey:@"name"] isEqualToString:@"UnFollow"]) 
    {
        [sender setTitle:@"Follow" forState:UIControlStateNormal];
    }
}

答案 4 :(得分:0)

您正在重复使用单元格,因此请在AuthorsListTableViewCell中实现此方法:

-(void) prepareForReuse{
  [super prepareForReuse];
  [self.btn_followOrUnfollow setTitle:@"Follow" forState:UIControlStateNormal];
}

//如果单元格是可重用的(具有重用标识符),则在从表视图方法dequeueReusableCellWithIdentifier:返回单元格之前调用它。如果你覆盖,你必须调用super。 并为单元格设置正确的默认值。

我还建议以这种方式实施:

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

    static NSString *CellIdentifier = @"AuthorsListCell";
    AuthorsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
                                                                     forIndexPath:indexPath];

    cell.lbl_authorName.text = [dic_eachAuthor objectForKey:@"name"];
    cell.btn_followOrUnfollow.tag = indexPath.row;

    [cell.btn_followOrUnfollow setTitle:@"Follow forState:UIControlStateNormal];
    [cell.btn_followOrUnfollow setTitle:@"UnFollow" forState:UIControlStateSelected];

    if([dic_eachAuthor valueForKey:@"follow"]){
        cell.btn_followOrUnfollow.selected = YES;
    } else{
        cell.btn_followorUnfollow.selected = NO;
    }
    // action button method declarations
    [cell.btn_followOrUnfollow addTarget:self action:@selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}


    -(void)followOrUnfollow:(UIButton *)sender
{
    sender.selected = !sender.selected;

    if ([sender.titleLabel.text isEqualToString:@"Follow"]) {
        [dic_eachAuthor setValue:@"1" forKey:@"follow"];
    }
    else if ([sender.titleLabel.text isEqualToString:@"UnFollow"]) {
        [dic_eachAuthor setValue:nil forKey:@"follow"];
    }


}

在AuthorsListTableViewCell

-(void) prepareForReuse{
  [super prepareForReuse];
  self.btn_followOrUnfollow.selected = NO;
}