我有一个 UITableView 应该在不同的时间显示进度条,然后在完成时隐藏它们。但是,进度条并没有在应该消失的时候消失。
背景
我正在开发的应用程序旨在允许用户创建多媒体项目。其中一个视图显示了当前可用的所有音频文件的列表,还为用户提供了从多个来源导入其他文件的选项,包括他们的音乐库。
细节
为了处理从音乐库的导入,我使用了 Chris Adamson 在他的博客中发布的代码的变体。用户可以根据需要将尽可能多的导入排队,代码将自动按顺序导入它们。读/写部分在后台执行,并发出通知让应用程序的其余部分知道进程的状态。
用户可用的所有音频文件都显示在 UITableView 中。表格视图使用自定义单元格,其中包含一个标签(显示文件名)和一个进度条(除非歌曲处于中间导入状态,否则进度条始终隐藏)。
这是单元格的代码:
@interface AudioTableCell()
@property (nonatomic, strong) NSString *importingFileName;
@end
@implementation AudioTableCell
// ---------------------------------------------------------------------------------------------------------------------
- (void) prepareForReuse
{
// remove notification listeners to avoid creating duplicates
[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotifMusicLibMgrUpdateProgress object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotifMusicLibMgrFinishedImportingSong object:nil];
// reset cell properties to default values
self.isClickable = YES;
self.downloadProgress.hidden = YES;
}
// ---------------------------------------------------------------------------------------------------------------------
// called by view controller prior to deleting a cell
- (void) prepareCellForDeletion
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotifMusicLibMgrUpdateProgress object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotifMusicLibMgrFinishedImportingSong object:nil];
}
// ---------------------------------------------------------------------------------------------------------------------
// called by the view controller's cellForRowAtIndexPath method
- (void) configureCell
{
// by default, cell should be clickable and the progress bar should be hidden
self.isClickable = YES;
self.downloadProgress.hidden = YES;
// listen to the import manager for updates on the import's progress
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(importWasUpdated:)
name:kNotifMusicLibMgrUpdateProgress
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(importWasFinished:)
name:kNotifMusicLibMgrFinishedImportingSong
object:nil];
// when the cell is scrolled out of view, the progress bar is hidden
// need to remember if depicted song was in process of being downloaded
if (self.importingFileName.length > 0) {
if ([self.trackLabel.text isEqualToString:[self.importingFileName stringByAppendingPathExtension:@"m4a"]]) {
self.downloadProgress.hidden = NO;
self.isClickable = NO;
}
}
}
// ---------------------------------------------------------------------------------------------------------------------
// triggered when receiving a notification that a song has been imported successfully
- (void) importWasFinished:(NSNotification *)notification
{
// the notification will pass the name of the song that was imported
NSString *fileName = [notification.userInfo objectForKey:@"audioFileName"];
// if the song that was imported matches the song being displayed by the cell, hide the progress bar
// and make the cell clickable
if ([self.trackLabel.text isEqualToString:[fileName stringByAppendingPathExtension:@"m4a"]]) {
self.downloadProgress.hidden = YES;
self.isClickable = YES;
}
// if the song that was imported matches the song that was "saved" by the cell, clear the saved song
if ([self.importingFileName isEqualToString:fileName]) {
self.importingFileName = @"";
}
}
// ---------------------------------------------------------------------------------------------------------------------
// triggered when receiving a an update notification (currently 1/second)
- (void) importWasUpdated:(NSNotification *)notification
{
// the notification will pass the name of the song being imported, its progress, and the number of songs queued
NSString *fileName = [notification.userInfo objectForKey:@"audioFileName"];
double completion = [[notification.userInfo objectForKey:@"progress"] doubleValue];
// if the cell is displaying the song being imported, disable the cell and show a progress bar
// also, store the name of the song - this way, if the cell is reused for a different song, it will still remember
// the song being downloaded and can immediately display the progress bar when brought back into view
if ([self.trackLabel.text isEqualToString:[fileName stringByAppendingPathExtension:@"m4a"]])
{
self.isClickable = NO;
self.downloadProgress.hidden = NO;
[self.downloadProgress setProgress:completion];
self.importingFileName = fileName;
} else {
self.downloadProgress.hidden = YES;
self.isClickable = YES;
}
}
@end
如您所见,单元格侦听来自导入器的通知以确定何时隐藏/显示进度条。如果我只尝试导入一首歌曲,则不会出现重大问题(尽管歌曲完成时间和进度条隐藏时间之间似乎确实存在轻微延迟)。但是,如果我将多首歌曲排队,则进度条在所有歌曲完成之前都不会消失。更糟糕的是,将单元格滚动到视野之外会导致当单元格被重复使用时,进度条会出现一首不同的歌曲。
我已经使用 NSLog 语句和调试器测试了通知系统,它工作正常(“self.downloadProgressBar.hidden = YES;”部分在正确的时间被调用),但进度条仍然可见。在这一点上,我完全没有想法。任何和所有的帮助将不胜感激。
提前致谢。