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];
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With