保存按下的按钮状态 UITableViewCell
Save pressed button state UITableViewCell
我 UITableView
有动态单元格,这些单元格是自定义 UITableViewCell
子类的对象。
每个单元格在 UIImageView
中包含 UILabel
、UIImageView
和 UIButton
。为了清楚起见,它是一个播放流音频的音乐播放器。我的问题是保存按下的按钮状态,例如,当我的 UITableView
第一次加载时,所有按钮都处于 "deselected" 状态并且每个按钮都有 "play.png" 作为图像,然后如果我按下这个按钮它的图像更改为 "pause.png" 并且目标也更改。这很明显,但是如果我向上或向下滚动我的 UITableView
,即使我从未按下这些按钮,我也会看到带有 "pause" 按钮的单元格。我知道我必须在 NSMutableArray
中保存单元格按钮状态并且我已经这样做了,但我想我做错了。请帮我解决这个典型问题。
我的来源:
Play/pause切换方法:
-(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 方法:
- (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;
}
看起来如何:
当没有按下任何按钮时:
按播放键就可以了
向下滚动,看到在 "play" 按钮也被按下后的第四个单元格上(但实际上没有)
向上滚动可以看到 "play" 附近的单元格上移动的选定按钮状态确实被按下了
你们很亲近。问题是单元格被重复使用,按钮的状态可能不会被选中。因为暂停图像仅在被选中时显示,所以您只需要确保按钮被选中。您还需要确保在需要时未选中它。希望这能解决问题。
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];
}
我 UITableView
有动态单元格,这些单元格是自定义 UITableViewCell
子类的对象。
每个单元格在 UIImageView
中包含 UILabel
、UIImageView
和 UIButton
。为了清楚起见,它是一个播放流音频的音乐播放器。我的问题是保存按下的按钮状态,例如,当我的 UITableView
第一次加载时,所有按钮都处于 "deselected" 状态并且每个按钮都有 "play.png" 作为图像,然后如果我按下这个按钮它的图像更改为 "pause.png" 并且目标也更改。这很明显,但是如果我向上或向下滚动我的 UITableView
,即使我从未按下这些按钮,我也会看到带有 "pause" 按钮的单元格。我知道我必须在 NSMutableArray
中保存单元格按钮状态并且我已经这样做了,但我想我做错了。请帮我解决这个典型问题。
我的来源:
Play/pause切换方法:
-(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 方法:
- (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;
}
看起来如何:
当没有按下任何按钮时:
按播放键就可以了
向下滚动,看到在 "play" 按钮也被按下后的第四个单元格上(但实际上没有)
向上滚动可以看到 "play" 附近的单元格上移动的选定按钮状态确实被按下了
你们很亲近。问题是单元格被重复使用,按钮的状态可能不会被选中。因为暂停图像仅在被选中时显示,所以您只需要确保按钮被选中。您还需要确保在需要时未选中它。希望这能解决问题。
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];
}