views:

476

answers:

2

I am having an issue where I am trying to save whether a repeat image will show selected or not (it is created as a UIButton on a UITableViewCell created in IB).

The issue is that since the cell gets re-used randomly, the image gets reset or set somewhere else after you start scrolling. I've looked all over and the advice was to setup an NSMutableArray to store the button's selection state and I am doing that in an array called checkRepeatState

My question is: where do I put the if-then-else statement in the code to where it will actually change the button image based on if the checkRepeatState is set to 0 or 1 for the given cell that is coming back into view? Right now, the if-then-else statement I am using has absolutely no effect on the button image when it comes into view. I'm very confused at this point.

Thank you ahead of time for any insight you can give!!!

My code is as follows:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
// set up the cell

static NSString *CellIdentifier = @"PlayerCell";

PlayerCell *cell = (PlayerCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (!cell) {

    [[NSBundle mainBundle] loadNibNamed:@"PlayerNibCells" owner:self options:nil];
    cell = tmpCell;
    self.tmpCell = nil;

    NSLog(@"Creating a new cell");

}

// Display dark and light background in alternate rows -- see tableView:willDisplayCell:forRowAtIndexPath:.
cell.useDarkBackground = (indexPath.row % 2 == 0);

// Configure the data for the cell.

NSDictionary *dataItem = [soundCategories objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [dataItem objectForKey:@"AnimalName"];

label = (UILabel *)[cell viewWithTag:2];    
label.text = [dataItem objectForKey:@"Description"];

UIImageView *img;
img = (UIImageView *)[cell viewWithTag:3];
img.image = [UIImage imageNamed:[dataItem objectForKey:@"Icon"]];

NSInteger row = indexPath.row;
NSNumber *checkValue = [checkRepeatState objectAtIndex:row];
NSLog(@"checkValue is %d", [checkValue intValue]);
// Reusing cell; make sure it has correct image based on checkRepeatState value
UIButton *repeatbutton = (UIButton *)[cell viewWithTag:4];

if ([checkValue intValue] == 1) {
    NSLog(@"repeatbutton is selected");
    [repeatbutton setImage:[UIImage imageNamed:@"repeatselected.png"] forState:UIControlStateSelected];
    [repeatbutton setNeedsDisplay];
} else {
    NSLog(@"repeatbutton is NOT selected");
    [repeatbutton setImage:[UIImage imageNamed:@"repeat.png"] forState:UIControlStateNormal];
    [repeatbutton setNeedsDisplay];
}   

cell.accessoryType = UITableViewCellAccessoryNone;

return cell;
}
+1  A: 
[repeatbutton setImage:[UIImage imageNamed:@"repeatselected.png"] forState:UIControlStateSelected];

Are you also setting the button state to selected? If you just want the button to display a different image, use UIControlStateNormal. If you have set both a normal and selected image, then just set the selected state with repeatbutton.selected = YES.

drawnonward
I am setting that in the IBAction for the button elsewhere in another function (where I also set a selected value in the mutable array).This has something to do with UITableViewCell re-use and not with whether the button state is selected or not. When the table view cell is brought into view, it doesn't matter what the selection state is, the image is just randomly either repeat.png or repeatselected.png depending on if the cell got re-used from another cell or not.
iWasRobbed
You should be able to set the normal and selected images in the nib, and just set the selected state in `tableView:cellForRowAtIndexPath:` or ignore the selected state and always set the image for the normal state. Since you are not restoring the selected state, either image could show.
drawnonward
Gotcha, I set up the different images in viewDidLoad and that works fine. However, when I try to set selected or not, it shows images incorrectly based on how it re-uses the tableview cells. NSLogs are telling me correctly if it's a selected state or not.My real problem is if they select on of the many "repeat" buttons in the table view and then scroll down out of view, the repeat buttons image doesn't stay the same due to cell re-use. That's really what I'm trying to figure out. How to reset the cell or get it to properly set the image once the cell comes back into view.
iWasRobbed
your hints got me there! it works!!! thank goodness... i'll post the working code below and give you credit, thanks again!
iWasRobbed
A: 

Just wanted to share the working code with the help of drawnonward.. thanks again! hopefully other people can get helped by this code

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
// set up the cell
static NSString *CellIdentifier = @"PlayerCell";

PlayerCell *cell = (PlayerCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (!cell) {

    [[NSBundle mainBundle] loadNibNamed:@"PlayerNibCells" owner:self options:nil];
    cell = tmpCell;
    self.tmpCell = nil;

    NSLog(@"Creating a new cell");

            // this will setup the button images for each state initially to be changed later

    UIButton *repeatbutton;
    repeatbutton = (UIButton *)[cell viewWithTag:4];
    [repeatbutton setImage:[UIImage imageNamed:@"repeat.png"] forState:UIControlStateNormal];
    [repeatbutton setImage:[UIImage imageNamed:@"repeatselected.png"] forState:UIControlStateSelected];

}

// Display dark and light background in alternate rows -- see tableView:willDisplayCell:forRowAtIndexPath:.
cell.useDarkBackground = (indexPath.row % 2 == 0);

// Configure the data for the cell... this gets called when the row scrolls into view each and every time

NSDictionary *dataItem = [soundCategories objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [dataItem objectForKey:@"AnimalName"];

label = (UILabel *)[cell viewWithTag:2];    
label.text = [dataItem objectForKey:@"Description"];

UIImageView *img;
img = (UIImageView *)[cell viewWithTag:3];
img.image = [UIImage imageNamed:[dataItem objectForKey:@"Icon"]];

NSInteger row = indexPath.row;
NSNumber *checkValue = [checkRepeatState objectAtIndex:row];
NSLog(@"checkValue is %d", [checkValue intValue]);
// Reusing cell; make sure it has correct image based on checkRepeatState value
UIButton *repeatbutton = (UIButton *)[cell viewWithTag:4];

if ([checkValue intValue] == 1) {
    NSLog(@"repeatbutton is selected");
    [repeatbutton setSelected:YES];
} else {
    NSLog(@"repeatbutton is NOT selected");
    [repeatbutton setSelected:NO];
}   

cell.accessoryType = UITableViewCellAccessoryNone;

return cell;
}

and my repeat button function that gets called:

- (void)repeatButton:(UIButton *)sender {

NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
NSInteger row = indexPath.row;

// method for finding what button was pressed and changing the button image for repeat on/off

UITableViewCell *cell = (UITableViewCell*)[[sender superview] superview];

UIButton *repeatbutton;
repeatbutton = (UIButton *)[cell viewWithTag:4];

if ([sender isSelected]) {
    [checkRepeatState replaceObjectAtIndex:row withObject:[NSNumber numberWithBool:NO]];
    [sender setSelected:NO];
} else {
    [checkRepeatState replaceObjectAtIndex:row withObject:[NSNumber numberWithBool:YES]];
    [sender setSelected:YES];
}       

}
iWasRobbed