我的代码有点麻烦,我希望能在这里得到一些帮助
我有一个uitableview,在每个uitableviewcell中我放了一个单独的uislider。 每个uislider,用作音乐播放的进度条。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UIButton *button = nil;
UISlider *customSlider = nil;
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIImage *image = [UIImage imageNamed:@"button_play.png"];
button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(340.0, 10.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:@selector(playAudio:) forControlEvents:UIControlEventTouchUpInside];
button.tag = 4;
[cell.contentView addSubview:button];
customSlider = [[UISlider alloc] initWithFrame:CGRectMake(10, 45, 456, 20)];
customSlider.minimumValue = 0.0;
customSlider.maximumValue = 100.0;
customSlider.continuous = YES;
customSlider.tag = 3;
customSlider.value = 0.0;
[cell.contentView addSubview:customSlider];
}
else {
customSlider = (UISlider *)[cell.contentView viewWithTag:3];
button = (UIButton *)[cell.contentView viewWithTag:4];
}
return cell;
}
- (void) playAudio:(UIButton *)sender {
UIButton *button = (UIButton *)[sender superview];
UITableViewCell *currentCellTouched = (UITableViewCell *)[button superview];
UITableView *currentTable = (UITableView *)[currentCellTouched superview];
NSIndexPath *indexPath = [currentTable indexPathForCell:currentCellTouched];
//currentCellPlaying type of UITableViewCell and accessible from the rest classe
currentCellPlaying = currentCellTouched;
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:NSLocalizedString([listFilesAudio objectAtIndex:indexPath.row], @"") ofType:@"mp3"]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
player.delegate = self;
[player prepareToPlay];
[(UISlider *)[currentCellTouched.contentView viewWithTag:3] setMaximumValue:[player duration]];
[(UISlider *)[currentCellTouched.contentView viewWithTag:3] setValue:0.0];
NSTimer *sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
[player play];
}
- (void)updateTime:(NSTimer *)timer {
[(UISlider *)[currentCellPlaying.contentView viewWithTag:3] setValue:player.currentTime];
}
当我发布单个游戏时,一切正常,进度条会更新。
我的问题是,当我向下/向上滚动桌面视图时,播放音乐的单元格消失,一旦我们回到播放音乐的单元格上,uislider就会回到0,并且不再更新。 ..(NSLOG确认我们仍然进入“updateTime”方法)
如果你有解决我问题的方法,我会很高兴看到它。
提前谢谢。
答案 0 :(得分:2)
Otium的答案并不完全正确,但它的方向是正确的。 celle并不是完全相同的对象,但是(实际上你是这样实现的)通过滚动离开可见区域的单元格被重新用于显示其他对象,滚动到可见区域。因此,当播放音乐的单元格再次可见时,另一个滑块对象会在其中显示原始单元格。此外,currentCellPlaying
对象(可能)不再显示或显示为另一个单元格。因此,当您更新viewWithTag:3
时,您(有时)不会看到它。
你应该做的是存储“indexCurrentPlaying”而不是单元格或滑块引用。使用该索引,您可以在cellForRowAt
的末尾装饰单元格....并且您可以更新updateTime
内该索引处的单元格的滑块。
希望有所帮助。
编辑:
一些未经测试的代码应该有效(可能有一些修复,但它解释了这个想法,我认为):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIButton *button = nil;
UISlider *customSlider = nil;
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIImage *image = [UIImage imageNamed:@"button_play.png"];
button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(340.0, 10.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:@selector(playAudio:) forControlEvents:UIControlEventTouchUpInside];
button.tag = 4;
[cell.contentView addSubview:button];
customSlider = [[UISlider alloc] initWithFrame:CGRectMake(10, 45, 456, 20)];
customSlider.minimumValue = 0.0;
customSlider.maximumValue = 100.0;
customSlider.continuous = YES;
customSlider.tag = 3;
customSlider.value = 0.0;
[cell.contentView addSubview:customSlider];
}
else
{
customSlider = [cell viewWithTag:3];
}
if([indexPath isEqual:currentPlayingIndexPath])
{
currentPlayingSlider = customSlider;
[self updateTime];
}
else if(customSlider == currentPlayingSlider)
{
currentPlayingSlider = nil;
}
return cell;
}
- (void) playAudio
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:NSLocalizedString([listFilesAudio objectAtIndex:currentPlayingIndexPath.row], @"") ofType:@"mp3"]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
player.delegate = self;
[player prepareToPlay];
NSTimer *sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
[player play];
}
- (void)updateTime:(NSTimer *)timer
{
[currentPlayingSlider setValue:player.currentTime];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
currentPlayingIndexPath = indexPath;
currentPlayingSlider = [cellForRowAtIndexPath: currentPlayingIndexPath];
[self playAudio];
}
小心NSIndexPath isEqual
。似乎在不同版本的SDK(look here)中回答不同的问题...因为您只需要行,所以可以将其更改为currentPlayingIndexPath.row == indexPath.row
答案 1 :(得分:0)
UItableView使用可出现的单元格,因此所有单元格基本上都是相同的对象。在cellForRowAtIndexPath方法中,您应该再次设置滑块的进度。