Ios 重用的单元格具有上一个单元格的UIView
我的视图控制器中有一个Ios 重用的单元格具有上一个单元格的UIView,ios,objective-c,cocoa-touch,uitableview,Ios,Objective C,Cocoa Touch,Uitableview,我的视图控制器中有一个tableview,每个tableview单元格都与一个音频文件关联。我使用的自定义tableview单元格内部有UIView。每个单元格的UIView都有一个唯一的UIBezierPath,以蓝色笔划。点击单元格时,didSelectRowForIndexPath开始播放音频文件,蓝色的UIBezierPath将与音频文件进度相关的红色UIBezierPath划过 float progress = playTime/duration; self.redWave.stro
tableview
,每个tableview单元格都与一个音频文件关联。我使用的自定义tableview单元格内部有UIView
。每个单元格的UIView都有一个唯一的UIBezierPath
,以蓝色笔划。点击单元格时,didSelectRowForIndexPath
开始播放音频文件,蓝色的UIBezierPath将与音频文件进度相关的红色UIBezierPath划过
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
这很好用。我注意到,当我点击第一个单元格时,音频将开始播放,红色路径将开始被抚摸——这是应该发生的,但如果我在这一过程中向下滚动,我点击的第五个单元格具有相同的UIBezierPath,它也在蓝色路径上抚摸红色路径!很明显,电池正在重复使用。此外,这不仅仅发生在我点击一个单元格时——加载tableview时,默认情况下,前5个单元格的UIBezierPath会复制到下一组5个单元格中。我不知道如何避开这件事。有什么想法吗
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
- (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;
}
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
didselectRowatingIndexPath
在mytableViewCell
类中调用以下方法:
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
-(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];
}
表视图旨在重用这些行。这是一项可以提高应用程序性能的功能,尤其是当您的表视图中包含大量元素时
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
由于表视图重用了它们的行,因此需要在回收行之前手动清除它们。如果通过创建UITableViewCell子类来实现单元格,则可以覆盖其
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
-(作废)预先准备
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
方法。每次要重新使用单元格时,都会调用它,这是进行可能需要的任何清理的最佳位置。许多在tableview单元格中播放媒体的应用程序(例如tumblr)会在单元格滚动时停止播放(可能使用prepareForReuse)
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
如果要继续播放,则需要将与该播放相关联的所有状态保留在表格单元(在模型中)之外,包括播放进度。您的自定义单元格应准备好指示从任何点(0-99%)开始的播放进度。当一个单元格进入视图时(在您的数据源cellforrowatinexpath
),您需要检查您的模型,查看该单元格的媒体是否正在播放,并让它绘制当前进度(希望它有一个方法setProgress:(float)进度
,用于更改进度属性并告知bezier工程视图需要显示
)
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;
这也意味着,如果设置了一个计时器来检查媒体播放进度,那么它的目标不能是单元格,而是维护模型的视图控制器。您是否尝试了
dequeueReusableCellWithIdentifier:forIndexPath:
?@mckeejm我尝试了OSAudioTableCell*单元格=[self.audioTable dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
没有任何区别:(+1我不知道这个prepareforeuse
方法。我总是在从返回单元格之前重置单元格-tableView:cellforRowAtIndexPath:
这种方法的问题是,如果我选择一个单元格并在文件仍在播放时向下滚动,然后滚动回我选择的单元格,这将导致红色部分h设置为零,使其看起来好像我从未选择过单元格。具体来说,“任何清理”是什么意思。您能给出任何您希望“清理”的一般示例吗?我遇到了与此问题类似的问题,我不清楚这有什么好处。谢谢。@Brosef Your view controller(或处理单元配置的任何内容)将需要跟踪选定的单元格以及每个音频文件所用的时间。这样,每次选定的单元格出现在屏幕上时,都可以正确地重新绘制红线。@tpdietz假设您的每个表视图单元格都有一个图像视图,并且图像视图显示的图像是从INTERNET。在图像下载之前,您希望显示某种占位符。在这种情况下,您的清理过程可能涉及取消任何正在进行的单元格下载操作,并将其图像视图的图像重置为占位符。我有一个名为OSTablePlayerController
的NSObject
类作为音频播放器及其所有功能(启动、停止)作为属性。但是,我从我的表视图单元格类中分配并初始化它。我的表视图单元格类还具有检测进度的计时器。因此我需要将所有这些移动到我的视图控制器?是的,并将其目标/操作设置到视图控制器。在那里,您需要确定模型中的哪一行正在播放并更新它的进度(模型需要保持播放进度,因为您不能依赖周围的单元格)。知道为什么第二组5个单元格与第一组5个单元格具有相同的UIView路径吗?
float progress = playTime/duration;
self.redWave.strokeEnd = self.progress;