Stavash's answer is the best, but if you don't want to do that, alternatively you can use tableView:cellForRowAtIndexPath:
. I saw that you tried that and that the state of the button was lost while scrolling. I assume this is due to cell reuse. With cell reuse, once a table view cell goes off the screen, it is cached with an identifier and then the next cell to come on the screen retrieves a cell with a given identifier from the cache.
To avoid the button losing its state when it goes off the screen, you can use multiple reuse identifiers and store the states of your buttons in an array. We'll call this property buttonStates
(it should be a mutable array).
Initialize your buttonStates
variable and add strings to represent "base states." Add as many of these strings as the number of cells in your table (I assume there is only one section based on your code).
When the state changes (this would probably happen in your copyPressedFromCell:
method, update the object at the index of the button's tag (which you have already set to the index of the cell) with a string representing the new state.
With all that done, make your cellForRowAtIndexPath:
method looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = self.buttonStates[indexPath.row];
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
Before we continue lets take a look at some of your willDisplayCell:
code (which should be moved here).
UIImageView *cellBottomLine = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, CELL_HEIGHT, 320.0, 1)];
cellBottomLine.image = [UIImage imageNamed:@"bottomCellImage.png"];
if (cellBottomLine.subviews) {
[cell addSubview:cellBottomLine];
}
Why are you running that if statement? If you've just created a new image view, it's going to return YES
every time (assuming that the array of subviews is not nil
by default). You would rather check if a bottom cell image already exists within the cell's subviews. But we don't even need to do that. Just add the image in the cellForRowAtIndexPath:
method, inside the !cell
if. That way, we only add the bottomCellImage
if the cell hasn't been created yet.
The same thing goes for your if (!copyButton.superview)
call. Continuing where we left of in our cellForRowAtIndexPath:
method:
UIImageView *cellBottomLine = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, CELL_HEIGHT, 320.0, 1)];
cellBottomLine.image = [UIImage imageNamed:@"bottomCellImage.png"];
[cell addSubview:cellBottomLine];
copyButton = [BSFunctions createButtonWithNormalImageNamed:@"copyCellButton.png"
highlightedImageName:@"copyCellButtonPressed.png"
target:self
selector:@selector(copyPressedFromCell:)];
[copyButton setFrame:CGRectMake(250, 10, 62, 32.5)];
copyButton.tag = indexPath.row;
[cell addSubview:copyButton];
}
UIButton *button = [cell viewWithTag:indexPath.row]; // Get the copy button
// Update the state of the button here based on CellIdentifier, outside the if statement so that it gets updated no matter what
// Also configure your cell with any non-button related stuffs here
return cell;
}