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:
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 up and see that selected button state moved on cell near "play" was really pressed
AVMDataStore *oneItem
instance itself by a property likeisPlaying
. So incellForRowAtIndexPath:
method you need to check only that value(isPlaying
) to set button status. and set corresponding values inIBAction
method toisPlaying
property. – Akhilrajtr