我有一个UITableView正在播放一个来自互联网的音频剪辑。音频剪辑正在与一个单例助手一起播放。当用户点击单元格中的按钮时,音频剪辑就开始了,并且进度指示符显示已经播放了多少音频剪辑,这是可行的。使用这个单例,我传入一个更新进度块,它在播放时更新单元格。
但是,当我在剪辑列表中滚动时,进度指示符将继续用于其他UITableViewCells。我的猜测是,当我在cellForRowAtIndexPath中调用cellForRowAtIndexPath时,它将返回当前由播放单例音频更新的单元格。我怎样才能解决这个问题?
编辑:这里的主要问题是,在播放playButtonPressed中的声音之后,我正在传递一个进度块。我每0.5秒更新一次进度。换句话说,如果我在cellForRow中将进度设置为0或类似的东西,它将在0.5秒后返回到当前进度。
[[Singleton sharedInstance] playURL:url completionHandler:^{
cell.playButton.selected = NO;
} errorHandler:^{
cell.playButton.selected = NO;
} progressHandler:^(float progress) {
if (cell.playButton.selected) {
[cell.progressView setProgress:progress animated:YES];
}
}];发布于 2015-08-14 18:40:21
假设您使用的是自定义的UITableViewCell子类,那么处理这个问题的最好方法可能是重写单元格类中的prepareForReuse。在这里,您可以隐藏进度指示符,将其全部删除,将其重置为零或应用程序中最有意义的任何内容:
override func prepareForReuse() {
super.prepareForReuse()
progressView.progress = 0 // Or otherwise reset the progress view
}prepareForReuse被调用-顾名思义,在从重用队列中取出单元之前,- just将再次使用。您可以使用它将您的单元格重新置于为特定索引路径执行的任何设置都会被重置的状态。
或者,根据您的设置,可能更有意义的是,在每个单元格退出队列时只查看它,并根据它是否是当前表示音频助手播放的剪辑的单元格来重置进度指示符。
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! MyCell
if indexPath.row == audioPlayer.indexOfTrackBeingPlayed {
cell.progressView.progress = audioPlayer.currentProgress
} else {
cell.progressView.progress = 0
}
}编辑:
添加到问题中的update块的问题是,您正在捕获该块中的特定单元格,但是该单元格随后会在表的其他位置被重用。相反,您需要使用indexPath从块内部获取单元格,因此它总是得到正确的单元格。例如:
[[Singleton sharedInstance] playURL:url completionHandler:^{
MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.playButton.selected = NO;
} errorHandler:^{
MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.playButton.selected = NO;
} progressHandler:^(float progress) {
MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (cell.playButton.selected) {
[cell.progressView setProgress:progress animated:YES];
}
}];必须在每个块内这样做有点麻烦,但这是必要的。通过定义一个方便的属性,您可以使它更加整洁:
@property(nonatomic, readonly) MyCell *playingCell;
- (MyCell *)playingCell {
NSIndexPath *playingIndexPath = // get the index path of the playing item
return [self.tableView cellForRowAtIndexPath:playingIndexPath];
}然后将块中的cell替换为self.playingCell。
发布于 2015-08-14 18:45:06
之所以会发生这种情况,是因为UITableView重用tableViewCells,可以根据单元的可用性为多个indexPaths调用一个单元。有几种方法可以解决这个问题
cellForRowAtIndexPath中的重置进度和单元用户界面,https://stackoverflow.com/questions/32016323
复制相似问题