In one of my view controllers I have a tableview
with custom tableviewcells
. Each cell is associated with a unique audio file. Each cell also has a progress bar. When I tap the cells to play the audio file and scroll down, I notice that the progress bar of the reused cell is also updating. I created a custom NSObject
class called OSTablePlayerController that contains the AVAudioPlayer
and its functionality. However, I set the NSTimer
within my custom tableviewcell
class. When I tap a cell to play the following method gets called within my custom 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];
}
- (void)updateProgress:(NSTimer *)timer
{
NSTimeInterval playTime = [self.audioPlayer currentTime];
NSTimeInterval duration = [self.audioPlayer duration];
float progress = playTime/duration;
[self.waveView setProgress:progress];
if(!(self.audioPlayer.player.playing))
{
[self audioPlayerDidFinishPlaying:self.audioPlayer.player successfully:YES];
progress = 0.00;
[self.waveView setProgress:progress];
}
}
-(void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if(flag)
{
[self.timer invalidate];
self.audioPlayer.isPlayerPlaying = NO;
}
}
The only other functionality I have implemented is pause, so that when a cell is tapped while it is already playing, the player would get paused. Tapping it again would start the player from where it was paused.
Anyone have recommendations on how to go about doing this the right way? I expect this to get pretty messy.
EDIT: Attempting to incorporate delegate methods.
//Custom tableview cell class .h
@class OSAudioTableCell;
@protocol progressDelegate <NSObject>
-(float) trackProgress;
@end
@interface OSAudioTableCell : UITableViewCell <AVAudioPlayerDelegate>
{
}
@property (nonatomic, weak) id<progressDelegate> delegate;
//Custom table view cell .m file
-(void) rowSelected2
{
[self.waveView setProgress:[self.delegate trackProgress]];
}
-(void) prepareForReuse
{
[super prepareForReuse];
[self.timer invalidate];
self.waveView.progress = 0;
}
//view controller with tableview
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[((OSAudioTableCell*)[self.audioTable cellForRowAtIndexPath:indexPath]) rowSelected2];
self.audioPlayer = [[OSTablePlayerController alloc] init];
[self.audioPlayer playAudio:data];
self.audioPlayer.isPlayerPlaying = YES;
self.audioPlayer.playerTimer =[NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(trackProgress:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.audioPlayer.playerTimer forMode:NSRunLoopCommonModes];
}
-(float) trackProgress
{
NSTimeInterval playTime = [self.audioPlayer currentTime];
NSTimeInterval duration = [self.audioPlayer duration];
float progress = playTime/duration;
if(!(self.audioPlayer.player.playing))
{
[self audioPlayerDidFinishPlaying:self.audioPlayer.player successfully:YES];
progress = 0.00;
}
return progress;
}