重用的单元格具有来自先前单元格的UIView

时间:2014-07-31 01:17:34

标签: ios objective-c cocoa-touch uitableview

我的视图控制器中有一个tableview,每个tableview cell都与一个音频文件相关联。我正在使用内部有UIView的自定义tableview单元格。每个单元格的UIView都有一个以蓝色描边的唯一UIBezierPath。当点击该单元时,didSelectRowForIndexPath启动播放音频文件,并且使用与音频文件的进度相关的红色UIBezierPath来描边蓝色UIBezierPath。

float progress =  playTime/duration;
self.redWave.strokeEnd = self.progress;

这很好用。我注意到的是,当我点击第一个单元格时,音频将开始播放,红色路径将开始被描边 - 这可能会发生,但如果我在发生这种情况时向下滚动,则第五个单元格从我点击了同样的UIBezierPath,它也在蓝色路径上划出红色路径!很明显,细胞正在被重复使用。此外,当我点击一个单元格时,这不仅仅发生了 - 当我的tableview加载时,默认情况下,前5个单元格中的UIBezierPath会复制到下一组5个单元格中。我不知道怎么解决这个问题。有什么想法吗?

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

    static NSString* identifier = @"audioTableCell";

    OSAudioTableCell *cell = [self.audioTable dequeueReusableCellWithIdentifier:identifier];

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

    }

        //Pull data from NSFetchResultsController
        Recording * recording = [self.managedDocument.frc objectAtIndexPath:indexPath];

        cell.waveView.minAmpl = [recording.minAmpl floatValue];

        //UIBezierPath Data
        NSData * pathData = recording.waveData;

        //set path for UIView (waveView is custom UIView class)
        cell.waveView.path = [NSKeyedUnarchiver unarchiveObjectWithData:pathData];
        [cell setImageSize:cell.waveView.bounds.size];

        cell.tag = indexPath.row;

        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        //tableCell textfield 
        NSString * track = @"Track";
        NSInteger row = indexPath.row;
        row = [self.managedDocument.frc.fetchedObjects count] - row;
        track = [track stringByAppendingFormat:@" %li",(long)row];
        cell.trackLabel.text = track;
        [cell.textField setFont:[UIFont fontWithName:@"Raleway-SemiBold" size:12]];
        cell.textField.delegate = self;

        if([recording.trackTitle isEqualToString:@""])
        {
            cell.textField.text = track;
        }
        else
        {
            cell.textField.text = recording.trackTitle;

        }

        UIColor * circleColor = [UIColor colorWithRed:107/255.0f green:212/255.0f blue:231/255.0f alpha:1.0f];

        cell.trackIcon.backgroundColor = circleColor;

        [cell.trackIcon.layer setCornerRadius:cell.trackIcon.bounds.size.width/2];

        cell.trackIcon.layer.masksToBounds = YES;


return cell;

}

didSelectRowAtIndexPath在我的tableViewCell课程中调用以下方法:

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

    self.audioPlayer = [OSTablePlayerController getInstance];
    NSData *data=[NSData dataWithContentsOfURL:url];
    [self.audioPlayer playAudio:data];
    self.audioPlayer.isPlayerPlaying = YES;
    self.timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

 }

2 个答案:

答案 0 :(得分:6)

表视图旨在重用行。这是一项可以提高应用性能的功能,尤其是当您的表格视图中包含大量元素时。

由于表视图重用了它们的行,因此您需要在回收行之前手动清除它们。如果通过创建UITableViewCell子类来实现单元格,则可以覆盖其

- (void)prepareForReuse

方法。每次要重用一个单元时都会调用它,这是进行任何可能需要进行的清理的理想位置。

答案 1 :(得分:0)

许多在tableview单元格中播放媒体的应用程序(例如tumblr)会在单元格滚动时停止播放(可能使用prepareForReuse)。

如果要继续播放,则需要在表格单元格(在模型中)之外保留与该播放相关的所有状态,包括播放进度。您的自定义单元格应准备好从任何点开始指示播放进度(从0-99%)。当一个单元格进入视图时(在您的数据源cellForRowAtIndexPath中),您将需要检查您的模型以查看该单元格的介质是否正在播放并让它绘制当前进度(希望它有一个方法{{1更改progress属性并告诉bezier绘图视图到setProgress:(float)progress)。

这也意味着如果设置了一个定时器来检查媒体播放进度,它的目标不能是单元格,而是维护模型的视图控制器。