Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reused cell has UIView from previous cell

I have a tableview in my view-controller and each tableview cell is associated with an audio file. I'm using custom tableview cells that have a UIView inside. The UIView for each cell has a unique UIBezierPath that is stroked in blue. When the cell is tapped, didSelectRowForIndexPath initiates playing the audio file and the blue UIBezierPath is stroked over with a red UIBezierPath in relation to the progress of the audio file.

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

This is working just fine. What I noticed is that when I tap the first cell, the audio will start playing and the red path will begin to get stroked - which is suppose to happen, but if I scroll down while this is happening, the 5th cell down from the one I tapped has the same UIBezierPath and it is also stroking the red path over the blue path! Its clear that the cell is being reused. Also, this isn't just happening when I tap a cell - the UIBezierPath's of the first 5 cells are replicated in the next set of 5 cells by default when my tableview loads. I don't know how to get around this. Any ideas?

- (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 calls the following method in my tableViewCell class:

-(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];

 }
like image 948
Brosef Avatar asked Mar 18 '23 21:03

Brosef


1 Answers

Table views are designed to reuse the rows. It's a feature that can improve the performance of your app, especially if your table view has a lot of elements in it.

Since table views reuse their rows, you need to manually clear your rows before they are recycled. If you implemented your cells by creating a UITableViewCell subclass, then you can override its

- (void)prepareForReuse

method. This gets called each time a cell is about to be reused, and it is the perfect location for doing any clean up that might need to happen.

like image 198
martega Avatar answered Mar 24 '23 14:03

martega