Cell的进度条在其他单元格上重复

时间:2015-05-26 08:53:18

标签: ios uitableview progress-bar tableviewcell reuseidentifier

我有一个细胞重用问题。

我的所有细胞都相同,只有一个部分。单元格包括标签,按钮和进度条。

按钮触发声音(这是一个简单的“播放”按钮)。当调用AVAudioPlayers委托方法audioPlayerDidFinishPlaying:时,我会使更新进度条的NSTimer无效,隐藏进度条,并使音频播放器无效。

所有这些都发生在我的单元格类中,它继承自UITableViewCell

除了一件事之外,一切都像它应该的那样:

播放声音时滚动会在新细胞上显示相同的进度条。

因此,如果我点击第二个单元格,滚动时显示的第二个下一个单元格将向前移动一个进度条(并在声音结束时停止+隐藏)。

我会告诉你我的自定义单元格完整课程,我希望这会有所帮助。我真的不知道如何解决这个问题。我在cellForRow:中尝试了if语句,但没有任何真正的成功。

@implementation SoundItemTableViewCell

- (void)awakeFromNib {
    // Initialization code
    self.progressBar.hidden = YES;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (IBAction)playSound:(id)sender {

    [self.progressBar setProgress:0];
    self.progressBar.hidden = NO;

    NSString *filename = self.fileName;
    [self playSoundWithURL:[NSURL URLWithString:filename]];
}

- (void)playSoundWithURL:(NSURL*)url{


    NSError *error;
    if (self.audioPlayer){

        if(self.audioPlayer.playing){
            [self.audioPlayer stop];
        }
    }

    self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
    self.audioPlayer.delegate = self;
    self.tmrProgress = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(updateElapsedTime) userInfo:nil repeats:YES];

    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];
    NSLog(@"Starting sound play with item : %@",url);

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

    [self.progressBar setProgress:0 animated:YES];
    self.progressBar.hidden = YES;
    //self.progressBar = nil;
    [self.tmrProgress invalidate];
    self.tmrProgress = nil;
    player = nil;
    self.audioPlayer = nil;
    NSLog(@"Audio Finish");
}


- (void)updateElapsedTime{
    if (self.audioPlayer) {
        NSLog(@"Updating progress");
        [self.progressBar setProgress:[self.audioPlayer currentTime] / [self.audioPlayer duration]];
    }
}

桌面视图。 pushList是一个包含文件网址的数组

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *identifier = @"SoundItemTableViewCell";
    SoundItemTableViewCell *cell = [self.tbPushList dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {
        cell = [[SoundItemTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    cell.fileName    = [pushList objectAtIndex:indexPath.row];
    cell.lbName.text = [[[pushList objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
    return cell;

}

我能做到的最好的方法就是在进度条出现时隐藏进度条,因此也没有其他进度条显示,但是重新进入我的播放单元然后会播放没有进度条的声音,这是不满意/不良的用户体验行为。

3 个答案:

答案 0 :(得分:4)

确保在cellForRowAtIndexPath:中初始化您单元格的所有属性 由于您的细胞正在被回收,它们将保留其现有的属性。

答案 1 :(得分:2)

问题是你正在重复使用你的音频层和周围的逻辑。你需要外部的东西来检查有问题的单元是否是播放声音的单元,你需要将控制器逻辑移动到控制器中。

将此属性添加到视图控制器...

@property (nonatomic) NSString *playingFilename;

- (IBAction)playSound:(id)sender移动到视图控制器中,并在选择特定按钮时设置字符串...

- (IBAction)playSound:(id)sender {

    UIButton *playButton = sender;
    NSInteger index = playButton.tag;

    SoundItemTableViewCell *cell = (SoundItemTableViewCell *)[self.tbPushList cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];

    [cell.progressBar setProgress:0];
    cell.progressBar.hidden = NO;

    self.playingFilename = [pushList objectAtIndex:index];

    // Personally I'd move the playing logic into the controller as well... spin up as many audio players as you need... but they shouldn't be in the cell.
    [self playSoundWithURL:[NSURL URLWithString:self.playingFileName]];
}

然后

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *identifier = @"SoundItemTableViewCell";
    SoundItemTableViewCell *cell = [self.tbPushList dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {
        cell = [[SoundItemTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }


   // tag your button.....
    cell.playButton.tag = indexPath.row;

    cell.lbName.text = [[[pushList objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];

    // check to see if this index contains the right file
   BOOL isRightFile = ([self.playingFilename isEqualToString:[pushList objectAtIndex:indexPath.row]])

    cell.progressBar.hidden = !isRightFile;

    return cell;
}

答案 2 :(得分:0)

在行方法的表格视图单元格中,检查是否选择了行,如果未选择该行,则将进度条的进度设置为零。