2

I am downloading images asynchronously and displaying them in a UITableView. While theimage is downloading, a UIProgressView should be displayed in the corresponding table row. After the download is complete, progress view should be replaced by the actual image.

I am using a storyboard and I subclassed UITableViewCell to a class called ResponseTableViewCell which has IBOutlets for a UIImageView responseView) and a UIProgressView (progressView). For some reason I can't manage to hide the progress view after the download is complete. If I don't hide it, it appears on top of the downloaded image. If I try to hide it, it is hidden for every row. I am guessing this has to do with reusing cells.

I have also tried creating two custom cells: One with a UIImageView and the other with a UIProgressView. But in a storyboard the only way I can add a UITableViewCell is by dragging it onto a UITableView which means I have two UITableViewCells on top of each other.

The only way that seems to work is programmatically creating the image view and progress view rather than subclassing UITableViewCell but I don't want to do it this way. Here is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ResponseTableViewCell *cell = (ResponseTableViewCell*)
    [tableView dequeueReusableCellWithIdentifier:@"ResponseCell"];

    if(indexPath.row == 0) {//display the main image

        cell.responseView.image = _image;
        [cell.progressView setHidden:YES];
        return cell;
    }
      //display responses to the image
      indexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section];
       Photo *response = [ self getResponseAtIndex:indexPath.row];
       NSMutableDictionary* downloadInfo = [self getConnectionInfoForId:[response photoId]];
       if([response fullImage] == nil) {
           float received = [[downloadInfo objectForKey:@"receivedBytes"] floatValue];
           float total = [[downloadInfo objectForKey:@"totalFileSize"] floatValue];

           NSNumber* percentage= [NSNumber numberWithFloat:received/total];
           NSMutableDictionary* userInfo = [[NSMutableDictionary alloc] init];
           [userInfo setObject:cell.progressView forKey:@"cell"];  
           [userInfo setObject:percentage forKey:@"percentage"];  /

           [self performSelectorOnMainThread:@selector(updateProgressView:) withObject:userInfo waitUntilDone:NO
];
           return cell;
        }
        else {
           cell.responseView.image = response.fullImage;
            return cell;
        }
}
ganime
  • 129
  • 2
  • 9

1 Answers1

0

I suspect this may have something to do with something outside the code you have posted. But the other issue is

        [cell.progressView setHidden:YES];

because I see that you have carefully updated the progressvView on the main thread later, but you don't execute the setHidden on the main thread. It's a UIProgressView, and UI code is supposed to be on the main thread, and maybe even something as small as setHidden counts.

emrys57
  • 6,679
  • 3
  • 39
  • 49
  • emrys57, yes you are right. After doing all UI updates in the main thread I am able to hide and show my progress view. But I still have one problem: although the "progress" value of my progress view is changed, the view is not updated accordingly. I can't see why as I am now doing all updates on the main thread. Maybe there is something else I am missing. Thanks. – ganime Nov 29 '12 at 13:22
  • The usual reason for the progress indicator not updating when it is properly changed on the main thread seems to be that the main thread never has a chance to run. Is it blocking, waiting for this thread? You could try, in your `performSelectorOnMainThread` call, specifying `waitUntilDone: YES`. It might work, but I can also see reasons why it might fail horribly, so, good luck! – emrys57 Nov 29 '12 at 13:44