当我滚动时,uitableviewcell 中的 UIslider 不再自动更新

Posted

技术标签:

【中文标题】当我滚动时,uitableviewcell 中的 UIslider 不再自动更新【英文标题】:Uislider in uitableviewcell is no more auto-updated when I scroll 【发布时间】:2012-04-04 21:22:12 【问题描述】:

我的代码有点问题,我希望在这里得到一些帮助

我有一个 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”方法)

如果你有我的问题的解决方案,我会很高兴阅读它。

提前谢谢你。

【问题讨论】:

【参考方案1】:

Otium 的回答并不完全正确,但它朝着正确的方向发展。单元格并非都是同一个对象,但是(实际上您是这样实现的)通过滚动离开可见区域的单元格被重用于显示其他单元格,滚动到可见区域。因此,当播放音乐的单元格再次可见时,another 滑块对象会在其中显示原来的滑块对象。此外,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

【讨论】:

对不起,我的回答有点简短:)【参考方案2】:

UItableView 使用可出队列的单元格,因此您的所有单元格基本上都是同一个对象。在 cellForRowAtIndexPath 方法中,您应该再次设置滑块的进度。

【讨论】:

以上是关于当我滚动时,uitableviewcell 中的 UIslider 不再自动更新的主要内容,如果未能解决你的问题,请参考以下文章

触摸 UITableViewCell 中的 UIButton 无法滚动表格

UItableviewcell中的pangesture,表格滚动无法快速工作

当我滚动 tableview 时,如何让 headerView 滚动(不停留在 tableview 的顶部)伴随 UItableViewCell

滚动时自定义uitableviewcell空白

Swift UITableViewCell 滚动时按钮状态更改

滚动 UITableView 时 iOS Expanded/Selected Custom UITableViewCells 状态变化