[UIProgressView在滚动uitableview时被隐藏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[UIProgressView在滚动uitableview时被隐藏相关的知识,希望对你有一定的参考价值。

我正在尝试使用asinetworkqueue下载URL列表。下载很好。但是,当我滚动uitableview时,我的uiprogressview被隐藏了。

我的意思是,如果进度显示在第2行中,并且如果滚动它,则进度视图将被隐藏。然后,在完成第2行的下载后,它将在第3行中显示进度视图。

简而言之,当滚动uitableview时,活动的uiprogressview被隐藏。

更新

这里还有一些澄清。当某行(例如第1行)的下载未完成时,现在,如果我滚动表格视图并看到第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);
    }
答案

[每次tableView询问您要在上面创建一个新单元的单元格–您都应该回收单元格是不正确的(Apple文档的此处和其他地方都有大量示例,有关如何执行此操作。]

现在,更新单元格中的进度条会遇到一些您没有处理的复杂性。首先,progressBar是对象,它会随着表的滚动而变化-它将从您下方改变。可以说您有一个部分可以简化步骤(但是这些步骤也可以用于多个部分):

因此,您只能通过执行以下操作来更新它:

  • 您的下载文件希望更新进度。它必须确定具有该进度条的表行(如果将进度条添加到单元格,则在该视图上设置标签可以使以后更容易找到它)

  • 上面的代码然后向UITableView询问可见单元的列表,并确定它需要更新的单元是否可见-如果不可见,则不执行任何操作。

  • 假设该单元格是可见的,它会向该单元格询问其progressBar(即[cell.contentView viewWithTag:...]),然后更新当前值(由于以下原因,此进度条可能先前已显示其他文件:回收)。

在cellForRowAtIndexPath中:您尝试回收一个单元,如果失败,则创建一个新单元。在该代码之后,您无法对任何视图进行任何假设-您需要更新progressBar max,将当前值设置为下载的当前值,更改任何标签文本,等等。

另一答案

一些观察:

  1. 您正在setDownloadProgressDelegate中设置ASINetworkQueue,但是如果要跟踪单个下载的进度,则可能需要在ASIHTTPRequest中进行。这样,理论上您可以相应地更新多个下载。

  2. 我说这的原因之一是,您当前正在创建networkQueue并添加一个ASIHTTPRequest并将其开始。从理论上讲,您可以排队一大堆ASIHTTPRequest并将它们踢开,每个更新它们各自的UIProgressView

  3. 最大的问题是您的cellForRowAtIndexPath

    • 首先,您不应该真正使用每个单元格的唯一标识符。您将失去所有的内存优化;

    • 您应该检查dequeueReusableCellWithIdentifier是否返回了nil(如果您将情节提要与原型单元一起使用,这不是问题,但我假设您不在这里进行此操作),如果这样做,则创建表格视图和您需要的任何控件;

    • 但是,无论dequeueReusableCellWithIdentifier是否返回nil,都应设置标签并更新进度条;和

    • 就个人而言,使用进度条,我发现更容易地删除进度条(如果已有的话),然后再次添加它,而不考虑dequeueReusableCellWithIdentifier是否成功。

  4. 您可能想要跟踪“行”对象的数组,例如,这些对象具有所下载内容的URL,但更重要的是,保留了UIProgressView对象(因为[C0 ]是downloadProgressDelegate属性,不会为您保留。因此,您需要跟踪当前所有正在处理的请求的进度条(无论单元格是否可见,是否已出队) ,而不仅仅是一个UIProgressView。

  5. 顺便说一句,您似乎正在将内容分发到后台队列。您实际上并不需要这样做,因为assign会为您完成所有此类工作。出于某种技术原因,您可能想要这样做,但是我认为这不是必需的,因为我认为这些工作已经异步进行了。如果您真的想在另一个队列中启动它,那很好,但是请记住将UI更新分派回主队列,因为您永远都不应从后台进行UI更新。

FYI,在下面的代码示例中,我使用了经常用于表视图的代码模式,特别是我的表视图具有一个模型,该模型由ASINetworkQueue个对象的NSArray组成,该模型跟踪我对每个对象的需求tableview的单元格。

Row

而且我将以如下方式使用它:

@interface Row : NSObject

@property (nonatomic, strong) NSString *author;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) UIProgressView *progress;
@property (nonatomic, strong) NSString *urlString;

@end

很显然,您必须根据自己的目的自定义此功能(例如,我出于自己的目的进行了调整;生活太短了,以至于我浪费时间写非ARC代码;等等),但这向您展示了我个人如何处理我认为这是您提供的代码示例的主要缺陷。我认为这需要大量扩展(如果我们离开,可以优雅地取消@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]; // fi

以上是关于[UIProgressView在滚动uitableview时被隐藏的主要内容,如果未能解决你的问题,请参考以下文章

可滚动且与 UITable 滚动同步的背景图像

向上滚动 UITable 后的 Swift 5 调用函数

通过从上到下滚动表格来刷新 UITable 内容

如何在 UITable 中实现 Instagram 评论的效果?

UITableViewCell 上的 UIProgressView

滚动表上的 ProgressView 块