1

コードに少し問題があり、ここで助けを得たいと思っていました

私は 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」メソッド内にまだ入っていることを確認します)

私の問題の解決策があれば、読んでいただければ幸いです。

前もって感謝します。

4

2 に答える 2

2

Otium の答えは完全に正しいわけではありませんが、正しい方向に進んでいます。セルはすべて同じオブジェクトではありませんが、(実際にはそのように実装しました)スクロールによって可視領域を離れたセルは、他のセルの表示に再利用され、可視領域にスクロールされます。そのため、音楽を再生しているセルが再び表示されると、元のスライダー オブジェクトの後に別のスライダー オブジェクトがその中に表示されます。さらに、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のバージョンが異なると答えが異なるようです(ここを見てください)...必要なのは行だけなので、次のように変更できますcurrentPlayingIndexPath.row == indexPath.row

于 2012-04-04T22:12:59.720 に答える
0

UItableViewはキューに入れることができるセルを使用するため、すべてのセルは基本的に同じオブジェクトです。cellForRowAtIndexPathメソッドで、スライダーの進行状況を再度設定する必要があります。

于 2012-04-04T21:27:20.377 に答える