Aleksander Aleksander - 5 days ago 5
iOS Question

Button added to tableview cell appears on other random cells as well

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

Answer

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

Comments