Question

I'm experiencing a problem with regards to adding a button to a tableview cell. Basically, I'm adding a button to a specific cell, but that button also appears on random other cells (not currently in the view).

When I tap a cell, I set a variable (tappedCell=indexPath), and reload that cell. In my cellForRowAtIndexPath I check if the indexPath is equal to the tappedCell, and if it is I add a button to it. That works, but this button also appears on other cells further down in the tableView. These cells are not in the view when I tap it, but further down, so I have to scroll to see them. If I keep scrolling up and down (quickly), more and more cells with buttons appears. This seems to be completely random.

I've tried adding a NSLog() inside the if-statement where I add the button, but this is not called more than once (when I tap the original cell). So it's actually not adding more buttons, it has to be the same one appearing in multiple cells.

I have no idea why this is happening. I've tried adding a button to every cell, and then just set hidden = YES as standard, and hidden = NO when the [self.tappedCell isEqual:indexPath], but this does not change anything...

Here you can see the code I use to add the button to my cell:

UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
[newBtn setImage:[UIImage imageNamed:@"open.png"] forState:UIControlStateNormal];
[newBtn setFrame:CGRectMake(220, 0, 100, 86)];
[newBtn addTarget:self action:@selector(openImage:) forControlEvents:UIControlEventTouchUpInside];                
[cell.contentView addSubview:newBtn]; 

I don't know what I'm doing wrong, or if I am doing something wrong at all. It's worth mentioning that I'm using a standard Apple/iOS style=subtitle cell, and not a custom one. This is to keep it consistent throughout my app (The cells are made in the storyboard, and I'm reusing a prototype cell).

Could anyone give me any insight on why it's behaving like it does, and how I can fix it?

Thanks in advance!

EDIT 1:

Here's my full code for cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Set up the item
    XYZItem *item = [self.itemsInView objectAtIndex:indexPath.row];
    NSString *CellIdentifier = @"itemPrototypeCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.textLabel.text = item.itemName;

    if ([self.selectedItem isEqual:indexPath]) 
    {
        cell.textLabel.numberOfLines = 2;

        UIButton *newBtn=[UIButton buttonWithType:UIButtonTypeCustom];
        [newBtn setImage:[UIImage imageNamed:@"open.png"] forState:UIControlStateNormal];
        [newBtn setFrame:CGRectMake(220, 0, 100, 86)];
        [newBtn addTarget:self action:@selector(openImage:) forControlEvents:UIControlEventTouchUpInside];

        [cell.contentView addSubview:newBtn];
    }

    NSString *detailTextLabelText = [NSString stringWithFormat:@"%lu subitems", (unsigned long)[item.subItems count]];
    cell.detailTextLabel.text = detailTextLabelText;

    return cell;
}
Was it helpful?

Solution

The button is showing up on cells that have reused a button that previously added it.

There are a few options here.

  1. Make the button part of every cell. Set it's .hidden property every time you create/reuse one to the appropriate value.
  2. Remove the button in the cell's prepareForReuse method.

Assuming self.tappedCell is a UITableViewCell subclass and indexPath is an index path, [self.tappedCell isEqual:indexPath] will always return NO

OTHER TIPS

I faced same issue and i also had multiple headers:

The solution is:

    if (!cell)
    {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];


        headerLabel = [[UILabel alloc] initWithFrame:
                                CGRectMake(15, 5, self.tableView.frame.size.width, 15.0)];

        headerLabel.backgroundColor = [UIColor clearColor];
        headerLabel.textAlignment = NSTextAlignmentLeft;
        [headerLabel setFont:[UIFont fontWithName:@"Helvetica Neue Medium" size:13.0]];
        headerLabel.tag = 1002;
         [cell.contentView addSubview:headerLabel];

        button =  [[UIButton alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, HEIGHTROW)];
        [button addTarget:self action:@selector(eventAddAlert) forControlEvents:UIControlEventTouchUpInside];
        [button setBackgroundImage:[UIImage imageNamed:@"add_manually.png"] forState:UIControlStateNormal];
        button.hidden = YES;
        button.tag = 1001;


      [cell.contentView addSubview:button];

    }else{

            // use viewWithTag to find lblNombre in the re-usable cell.contentView

         headerLabel = (UILabel *)[cell.contentView viewWithTag:1002];
        button = (UIButton *)[cell.contentView viewWithTag:1001];

    }

 if(indexPath.section == 0 && indexPath.row == 0){

        button.hidden = NO;


    }else{
       button.hidden = YES;
         .........
}

.........

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top