vendettacore
vendettacore

Reputation: 1509

Save pressed button state UITableViewCell

I've UITableView with dynamic cells and the cells are objects of custom UITableViewCell subclass. Each cell contains UILabel,UIImageView and UIButton inside this UIImageView. For clarity it is a music player which play's stream audio. My problem is saving pressed button state i.e for example when my UITableView first loaded all buttons are in "deselected" state and each button has "play.png" as image, then if I press on this button its image changes to "pause.png" and target change too. It's very obvious, but if I will scroll up or down my UITableView I'll see cells with "pause" button even if I never pressed on these buttons. I know that I must save cell button stae in NSMutableArray and I already do it, but I guess that I do it wrong. Please help me solve this typical problem.

My source:

Play/pause switch method:

-(void)selectSettings:(AVMPlayButton *)sender{

CGPoint pointInTable = [sender convertPoint:sender.bounds.origin toView:musicTable];
NSIndexPath *indexPath = [musicTable indexPathForRowAtPoint:pointInTable];
AVMMusicCell *cell=(AVMMusicCell *)[musicTable cellForRowAtIndexPath:indexPath];

NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
[sender setSelected:!sender.isSelected];

if (sender.isSelected) {
    NSLog(@"SELECTED!");

    if (![selectedButonsToPlay containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]  ) // HERE IS ARRAY WHICH CONTAINS SELECTED BUTTONS
    {
        [selectedButonsToPlay addObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]];
        [sender addTarget:self action:@selector(pausePlay:) forControlEvents:UIControlEventTouchUpInside];
        UIImage *pauseBackground = [UIImage imageNamed:@"pause.png"];
        [sender setImage:pauseBackground forState:UIControlStateSelected];
    }

}else {
    NSLog(@"DESELECTED!");
    if ( [selectedButonsToPlay containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]  )
    {
        [selectedButonsToPlay removeObject:[NSString stringWithFormat:@"%ld",(long)indexPath.row]];
        //    [cell.playButton addTarget:self action:@selector(startPlay:) forControlEvents:UIControlEventTouchUpInside];
        NSLog(@"DEselected in didDEselect");
        }
    }

NSLog(@"you just select button");
}


-(IBAction)pausePlay:(AVMPlayButton*)sender{
AVMPlayButton *settings = (AVMPlayButton *)sender;
CGPoint pointInTable = [settings convertPoint:settings.bounds.origin toView:musicTable];
NSIndexPath *indexPath = [musicTable indexPathForRowAtPoint:pointInTable];
AVMMusicCell *cell=(AVMMusicCell *)[musicTable cellForRowAtIndexPath:indexPath];
UIImage *playBackground = [UIImage imageNamed:@"play.png"];
[cell.playButton setImage:playBackground forState:UIControlStateNormal];
[self pauseStream];

}

CellForRowAtIndexPath method:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *CellIdentifier = @"fileCell";
   AVMMusicCell *cell = [self.musicTable dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[AVMMusicCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

AVMDataStore *oneItem = [musicArray objectAtIndex:indexPath.row];
oneItem = [musicArray objectAtIndex:indexPath.row];


[cell setMusic:oneItem];
cell.songName.text = oneItem.fileName;
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = MINT;
[cell setSelectedBackgroundView:bgColorView];

[cell.playButton addTarget:self action:@selector(selectSettings:) forControlEvents:UIControlEventTouchUpInside];

//save cell state for selected CELLS
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];

UIImage *pauseBackground = [UIImage imageNamed:@"pause.png"];
UIImage *playBackground = [UIImage imageNamed:@"play.png"];
if ([selectedButonsToPlay containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]  )
{
    NSLog(@"cellforrow %lu contains selected buttons!",indexPath.row);
  //  NSLog(@"picture in cell %lu button is %@",indexPath.row,cell.playButton.imageView.image);
   // [cell.playButton removeTarget:self action:@selector(selectSettings:) forControlEvents:UIControlEventTouchUpInside];
    [cell.playButton addTarget:self action:@selector(pausePlay:) forControlEvents:UIControlEventTouchUpInside];

    [cell.playButton setImage:pauseBackground forState:UIControlStateSelected];
}
else{
    NSLog(@"cell %lu does not contain selected buton",indexPath.row);
    [cell.playButton addTarget:self action:@selector(startPlay:) forControlEvents:UIControlEventTouchUpInside];
        [cell.playButton setImage:playBackground forState:UIControlStateNormal];
}


return cell;


}

How it looks like:

When no one button is pressed:

When no one button is pressed

Press play button and it's ok

Press play button and it's ok

Scroll down and see that on the fourth cell after "play" button is pressed too (but actually it's not)

Scroll down and see that on the fourth cell after "play" button is pressed too (but actually it's not)

Scroll up and see that selected button state moved on cell near "play" was really pressed Scroll up and see that selected button state moved on cell near "play" was really pressed

Upvotes: 2

Views: 1334

Answers (1)

Skyler Lauren
Skyler Lauren

Reputation: 3812

You are very close. The issue is that the cell is reused and the state of the button will likely not be selected. Because the pause image only shows up when selected you just need to make sure the button is selected. You will also want to make sure it is unselected when needed. Hopefully that fixes the problem.

if ([selectedButonsToPlay containsObject:[NSString stringWithFormat:@"%@",rowNsNum]]  )
{
    NSLog(@"cellforrow %lu contains selected buttons!",indexPath.row);
    //  NSLog(@"picture in cell %lu button is %@",indexPath.row,cell.playButton.imageView.image);
    // [cell.playButton removeTarget:self action:@selector(selectSettings:) forControlEvents:UIControlEventTouchUpInside];
    [cell.playButton addTarget:self action:@selector(pausePlay:) forControlEvents:UIControlEventTouchUpInside];

    [cell.playButton setImage:pauseBackground forState:UIControlStateSelected];

    [cell.playButton setSelected:YES];
}
else{
    NSLog(@"cell %lu does not contain selected buton",indexPath.row);
    [cell.playButton addTarget:self action:@selector(startPlay:) forControlEvents:UIControlEventTouchUpInside];
    [cell.playButton setImage:playBackground forState:UIControlStateNormal];

    [cell.playButton setSelected:NO];

}

Upvotes: 4

Related Questions