在iOS上,如何让cell.imageView刷新其内容?

nop*_*ole 3 iphone uitableview ios sendasynchronousrequest

我正在尝试tableView:cellForRowAtIndexPath通过调用来设置图像

[self downloadImage:urlString andSetIntoCellImageView:cell]
Run Code Online (Sandbox Code Playgroud)

downloadImage,它将调用NSURLConnection:sendAsynchronousRequest(仅限iOS 5及更高版本),并在完成块中,使用设置图像

cell.imageView.image = [UIImage imageWithData:data];   // data is downloaded data
Run Code Online (Sandbox Code Playgroud)

它是有效的,如果在tableView:cellForRowAtIndexPath,imageView填充虚拟占位符图像 - 我想知道如何刷新新图像,是否setNeedsDisplay重新绘制?但是,如果我没有设置占位符图像,那么新图像将根本不显示.我想知道可以使用什么机制来显示图像?

如果我使用

[cell.imageView setNeedsDisplay]
Run Code Online (Sandbox Code Playgroud)

要么

[cell setNeedsDisplay];
Run Code Online (Sandbox Code Playgroud)

在完成块中,它将无法工作,如果我使用

[self.table reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
                            withRowAnimation:UITableViewRowAnimationAutomatic];
Run Code Online (Sandbox Code Playgroud)

在完成块中通过downloadImage接受indexPath,它将tableView:cellForRowAtIndexPath再次调用,并导致无限循环.因此,我似乎需要使用一些哈希表来记住图像是否已经在哈希表中:如果没有,则调用downloadImage,如果在哈希表中,只需使用它,那么就不会有无限循环.

但是有一种简单的方法可以让图像显示出来吗?设置占位符图像有效,但如果我们不这样做 - 占位符导致图像刷新的机制是什么?

Car*_*zey 14

UITableViewCell-layoutSubviews方法被调用时,如果它的imageViewimage特性是nil,imageView被赋予的帧(0,0,0,0).此外,-layoutSubviews仅在某些情况下被调用:当单元格即将变为可见时以及何时被选中.不是在正常滚动期间.因此,您所看到的是将占位符内部tableView:cellForRowAtIndexPath:大小设置为cell.imageView非零大小,并且可以看到后续的图像更改.

我通过调用[cell setNeedsLayout]完成处理程序修复了这个问题,如下所示:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:MY_IMAGE_URL]];
[NSURLConnection sendAsynchronousRequest:request
                                   queue:self.operationQueue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                                UIImage *image = [UIImage imageWithData:data];
                                                cell.imageView.image = image;
                                                [cell setNeedsLayout];
                                            }];
Run Code Online (Sandbox Code Playgroud)

我发现完成块在后台发生,因此需要在主线程上执行我的UI工作.当然这个解决方案不会考虑细胞再利用等等,但至少解决了细胞图像不会出现的原因:)

希望这可以帮助!