我有一个UITableView应该在不同时间显示进度条,然后在完成时隐藏它们。然而,进度条并没有消失。
我正在开发的应用程序旨在让用户创建多媒体项目。其中一个视图显示了当前可用的所有音频文件的列表,还为用户提供了从多个源(包括其音乐库)导入其他文件的选项。
要处理音乐库的导入,我正在使用Chris Adamson在其博客here中发布的代码的变体。用户可以根据需要排队多少导入,代码将自动按顺序导入它们。读/写部分在后台执行,发送通知以让应用程序的其余部分知道进程的状态。
用户可用的所有音频文件都显示在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;”部分在正确的时间被调用),但进度条仍然可见。在这一点上,我完全没有想法。任何和所有的帮助将不胜感激。
提前致谢。
答案 0 :(得分:0)
请检查您的代码是否在主线程上执行。 NSNotification可以在后台线程上发布,因此您的代码将在后台线程上执行,而后台线程不会更新UI。