我正在尝试使用asinetworkqueue下载网址列表。下载正常。但是当我滚动uitableview时,我的uiprogressview被隐藏了。
我的意思是如果进度显示在第2行,如果我滚动它,则进度视图被隐藏。然后在完成第2行的下载之后,它将显示第3行的进度视图。
简而言之,当滚动uitableview时,活动的uiprogressview将被隐藏。
请帮助我克服这个问题。
非常感谢您的时间..
Upadated-实际问题:如果某行没有完成下载(例如第1行),现在如果我滚动tableview并看到第1行,则进度视图甚至会隐藏它还没有完成下载。一旦第1行完成下载,就会开始对第2行进行降码,现在显示进度视图。
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.jpg"]];
CGRect tblViewFrame = CGRectMake(7 , 0 , self.view.bounds.size.width - 14, self.view.bounds.size.height - 90);
self.tblViewDownload = [[[UITableView alloc]initWithFrame:tblViewFrame style:UITableViewStyleGrouped]autorelease];
self.tblViewDownload.backgroundColor = [UIColor clearColor];
self.tblViewDownload.showsVerticalScrollIndicator = FALSE;
self.tblViewDownload.scrollEnabled = YES;
self.tblViewDownload.delegate = self;
self.tblViewDownload.dataSource = self;
[self.view addSubview:self.tblViewDownload];
index = 0;
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[self loadArray];
}); // Do any additional setup after loading the view.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.myUrlArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:
(NSIndexPath *)indexPath
{
CGFloat rowHeight = 75.0;
return rowHeight;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *lblTitle, *lblAuthor;
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero]autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
lblTitle = [[[UILabel alloc]initWithFrame:CGRectMake(65, 10, 220, 25)]autorelease];
lblTitle.backgroundColor = [UIColor clearColor];
//lblTitle.font = [UIFont boldSystemFontOfSize:15.0];
lblTitle.font = [UIFont fontWithName:@"Palatino-Bold" size:15.0];
lblTitle.text = @"Sample title";
[cell.contentView addSubview:lblTitle];
lblAuthor = [[[UILabel alloc]initWithFrame:CGRectMake(65, 30, 220, 25)]autorelease];
lblAuthor.backgroundColor = [UIColor clearColor];
lblAuthor.font = [UIFont italicSystemFontOfSize:13.0];
lblAuthor.textColor = [UIColor grayColor];
lblAuthor.text = @"sample authior";
[cell.contentView addSubview:lblAuthor];
}
return cell;
}
-(void)loadArray{
NSString *urk = @"http://sample/iphone/video/video_2.mov";
self.myUrlArray = [[NSMutableArray alloc]init];
for( int i = 0;i<10;i++){
[self.myUrlArray addObject:urk];
}
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[self downLoadPoems];
});
}
-(void)downLoadPoems{
if( index < [myUrlArray count] )
{
NSLog(@"this is the index %d",index);
NSIndexPath *myIP = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *Cell = [self.tblViewDownload cellForRowAtIndexPath:myIP];
progress = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
progress.frame = CGRectMake(65, 55, 210, 25);
progress.progress = 0.0;
progress.backgroundColor = [UIColor redColor];
[Cell.contentView addSubview:progress];
}
if(!self.networkQueue)
self.networkQueue = [[[ASINetworkQueue alloc] init] autorelease];
[self.networkQueue cancelAllOperations];
[self.networkQueue setQueueDidFinishSelector:@selector(queueCompleted:)];
[self.networkQueue setShowAccurateProgress:YES];
[self.networkQueue setDownloadProgressDelegate:progress];
[self.networkQueue setDelegate:self];
if( index < [myUrlArray count] )
{
NSString *url = [myUrlArray objectAtIndex:index];
NSArray *aPoemArrayUrls = [NSArray arrayWithObjects:url,nil];
for(NSString* urlString in aPoemArrayUrls)
{
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *downloadAFileRequest = [[ASIHTTPRequest requestWithURL:url]retain];
NSString *Filename = [urlString lastPathComponent];
NSLog(@"%@ filename",Filename);
[downloadAFileRequest setUserInfo:[NSDictionary dictionaryWithObject:@"request1" forKey:@"name"]];
[downloadAFileRequest setDownloadDestinationPath:[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:Filename]];
[downloadAFileRequest setShouldContinueWhenAppEntersBackground:YES];
[downloadAFileRequest setDelegate:self];
[downloadAFileRequest setDidFinishSelector:@selector(requestDone:)];
[downloadAFileRequest setDidFailSelector:@selector(requestWentWrong:)];
[downloadAFileRequest setShowAccurateProgress:YES];
[self.networkQueue addOperation:downloadAFileRequest];
//----
}
[self.networkQueue go];
}
}
-(void)queueCompleted:(ASINetworkQueue*)queue{
NSLog(@"queueCompleted");
self.tblViewDownload.userInteractionEnabled = YES;
UIProgressView *progressv = (UIProgressView*)queue.downloadProgressDelegate;
if (progressv)
[progressv removeFromSuperview];
if ( index < [myUrlArray count] ){
index++;
[self downLoadPoems];
}
}
- (void)requestDone:(ASIHTTPRequest *)request
{
NSLog(@"request done");
NSString *response = [request responseString];
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSLog(@"request went wrong");
NSError *error = [request error];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
答案 0 :(得分:1)
每当tableView要求您创建一个上面的新单元格时 - 它是不正确的,您应该回收单元格(这里和Apple文档中有关如何执行此操作的大量示例。)
现在,更新单元格中的进度条有一些您没有处理的复杂性。首先,progressBar对象将随着表格的滚动而改变 - 它将从你的下方改变。假设您有一个部分可以简化步骤(但这些部分也适用于多个部分):
所以你应该只通过执行以下操作来更新它:
您的下载需要更新进度。它必须确定具有该进度条的表行(如果向单元格添加进度条,则在该视图上设置标记可以使以后更容易找到它)
上面的代码然后向UITableView询问可见单元格列表,并确定它需要更新的单元格是否可见 - 如果没有,则它什么也不做。
假设单元格是可见的,它会询问单元格的progressBar(即[cell.contentView viewWithTag:...]),然后更新当前值(此progess栏可能以前显示过其他文件)由于回收)。
在您的cellForRowAtIndexPath中:您尝试回收一个单元格,如果失败则创建一个新单元格。在该代码之后,您不能对任何视图做出任何假设 - 您需要更新progressBar max,将当前值设置为下载的当前值,更改任何标签文本等。
答案 1 :(得分:1)
有几点意见:
您在setDownloadProgressDelegate
中设置了ASINetworkQueue
,但如果您想跟踪各个下载的进度,可能需要在ASIHTTPRequest
中执行此操作。这样你理论上可以相应地更新多次下载。
我之所以这样说,原因之一就是您目前正在创建networkQueue
添加一个ASIHTTPRequest
并将其踢掉。从理论上讲,你可以将一大堆ASIHTTPRequest
排队并启动它们,每个都更新自己的UIProgressView
。
最大的问题是你的cellForRowAtIndexPath
。
首先,您不应该为每个使用唯一的单元格标识符。你失去了所有内存优化;
您应该检查dequeueReusableCellWithIdentifier
是否返回nil
(如果您使用带有原型单元格的故事板,则不会出现问题,但我假设您在这里没有这样做),如果有,则创建表格视图和您需要的任何控件;
但是,您应该设置标签并更新进度条,无论dequeueReusableCellWithIdentifier
是否返回nil
;以及
就个人而言,如果进度条已经存在,我会更容易删除进度条,然后再次添加,无论dequeueReusableCellWithIdentifier
是否成功。
您可能希望跟踪一系列“行”对象,例如,这些对象包含正在下载的内容的URL,但更重要的是,保留了UIProgressView
个对象(因为,烦人地) ,downloadProgressDelegate
是assign
属性,不会为您保留。因此,您需要跟踪当前正在进行的所有请求的进度条(无论是否为单元格)是否可见,是否已出列,而不仅仅是单一的UIProgressView。
顺便说一句,看起来你正在将东西发送到后台队列。你真的不需要这样做,因为ASINetworkQueue
为你做了所有这些事情。可能有技术上的原因,你可能想这样做,但我不认为这是必要的,因为我认为这些东西已经异步工作。如果你真的想在另一个队列中启动它,那很好,但只记得将你的UI更新发送回主队列,因为你永远不应该从后台进行UI更新。
仅供参考,在下面的代码示例中,我使用了经常用于tableviews的代码模式,特别是我的tableview有一个由Row
对象的NSArray组成的模型,它跟踪我需要的内容对于tableview的每个单元格。
@interface Row : NSObject
@property (nonatomic, strong) NSString *author;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) UIProgressView *progress;
@property (nonatomic, strong) NSString *urlString;
@end
我将使用它如下:
@interface SampleViewController ()
@property (nonatomic, strong) NSArray *rows;
@property (nonatomic, strong) ASINetworkQueue *networkQueue;
@end
@implementation SampleViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.rows = [self loadImageUrls];
[self downloadStuff];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.rows count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 75.0;
}
#define kTitleTag 1
#define kAuthorTag 2
#define kProgressViewTag 3
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = @"asi";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *lblTitle, *lblAuthor;
// if you could use storyboards, a lot of this silliness goes away
if (cell == nil)
{
// but in the world of nibs, you have to create the custom controls when you create the cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
lblTitle = [[UILabel alloc]initWithFrame:CGRectMake(65, 10, 220, 25)];
lblTitle.backgroundColor = [UIColor clearColor];
lblTitle.font = [UIFont boldSystemFontOfSize:15.0];
//lblTitle.font = [UIFont fontWithName:@"Palatino-Bold" size:15.0];
lblTitle.tag = kTitleTag;
[cell.contentView addSubview:lblTitle];
lblAuthor = [[UILabel alloc]initWithFrame:CGRectMake(65, 30, 220, 25)];
lblAuthor.backgroundColor = [UIColor clearColor];
lblAuthor.font = [UIFont italicSystemFontOfSize:13.0];
lblAuthor.textColor = [UIColor grayColor];
lblAuthor.tag = kAuthorTag;
[cell.contentView addSubview:lblAuthor];
}
else
{
// if you're recycling a cell, then link up with it's controls
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
lblTitle = (UILabel *)[cell.contentView viewWithTag:kTitleTag];
lblAuthor = (UILabel *)[cell.contentView viewWithTag:kAuthorTag];
UIProgressView *oldProgressView = (UIProgressView *)[cell.contentView viewWithTag:kProgressViewTag];
if (oldProgressView && [oldProgressView isKindOfClass:[UIProgressView class]])
{
[oldProgressView removeFromSuperview];
}
}
Row *row = [self.rows objectAtIndex:indexPath.row];
lblTitle.text = row.title;
lblAuthor.text = row.author;
if (row.progress)
{
row.progress.frame = CGRectMake(0, 55, 200, 25);
[cell.contentView addSubview:row.progress];
}
return cell;
}
-(void)downloadStuff
{
ASINetworkQueue *networkQueue = [[ASINetworkQueue alloc] init];
[networkQueue setQueueDidFinishSelector:@selector(queueCompleted:)];
[networkQueue setDelegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createDirectoryAtPath:[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"ASIHTTP"]
withIntermediateDirectories:NO
attributes:nil
error:nil];
for (NSUInteger i = 0; i < [self.rows count]; i++)
{
Row *row = [self.rows objectAtIndex:i];
row.progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
row.progress.tag = kProgressViewTag;
NSIndexPath *myIP = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:myIP];
if (cell)
{
// if the cell is visible, add the progress view to it
row.progress.frame = CGRectMake(0, 55, 200, 25);
[cell.contentView addSubview:row.progress];
}
NSString *urlString = row.urlString;
ASIHTTPRequest *request;
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:urlString]];
NSString *filename = [urlString lastPathComponent];
[request setUserInfo:[NSDictionary dictionaryWithObject:@"request1" forKey:@"name"]];
[request setDownloadDestinationPath:[[[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"ASIHTTP"] stringByAppendingPathComponent:filename] stringByAppendingFormat:@"%1d", i]];
[request setShouldContinueWhenAppEntersBackground:YES];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[request setDownloadProgressDelegate:row.progress];
[request setShowAccurateProgress:YES];
[networkQueue addOperation:request];
}
[networkQueue go];
}
-(void)queueCompleted:(ASINetworkQueue*)queue
{
NSLog(@"%s queueCompleted", __FUNCTION__);
}
- (void)requestDone:(ASIHTTPRequest *)request
{
NSLog(@"%s request done: %@", __FUNCTION__, [request responseString]);
[request.downloadProgressDelegate removeFromSuperview];
// find which row it's on and remove it from that one
for (Row *row in self.rows)
{
if (row.progress == request.downloadProgressDelegate)
row.progress = nil;
}
// and let it go (obviously, non-ARC, release)
request.downloadProgressDelegate = nil;
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSLog(@"%s request went wrong err = %@", __FUNCTION__, [request error]);
}
- (NSArray *)loadImageUrls
{
NSMutableArray *results = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < 100; i++)
{
Row *row = [[Row alloc] init];
row.urlString = @"http://host/test/bigfile";
row.title = [NSString stringWithFormat:@"Title %1d", i];
row.author = [NSString stringWithFormat:@"Author %1d", i];
[results addObject:row];
}
return results;
}
显然,你必须为自己的目的定制这个(例如我为了我自己的目的而调整;生命太短暂,我不能浪费时间编写非ARC代码;等等),但它告诉你我个人解决了我所看到的您提供的代码示例的主要缺陷。我认为这需要相当大的延伸(如果我们离开,可以优先取消ASINetworkQueue
,也许只为可见单元格加载ASIHTTPRequests
等等),但我会留给你。
答案 2 :(得分:0)
使用此方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero]autorelease];
UILabel *lblTitle, *lblAuthor;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
lblTitle = [[[UILabel alloc]initWithFrame:CGRectMake(65, 10, 220, 25)]autorelease];
lblTitle.backgroundColor = [UIColor clearColor];
//lblTitle.font = [UIFont boldSystemFontOfSize:15.0];
lblTitle.font = [UIFont fontWithName:@"Palatino-Bold" size:15.0];
lblTitle.text = @"Sample title";
[cell.contentView addSubview:lblTitle];
lblAuthor = [[[UILabel alloc]initWithFrame:CGRectMake(65, 30, 220, 25)]autorelease];
lblAuthor.backgroundColor = [UIColor clearColor];
lblAuthor.font = [UIFont italicSystemFontOfSize:13.0];
lblAuthor.textColor = [UIColor grayColor];
lblAuthor.text = @"sample authior";
[cell.contentView addSubview:lblAuthor];
return cell;
}