3

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

[self downloadImage:urlString andSetIntoCellImageView:cell]

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

cell.imageView.image = [UIImage imageWithData:data];   // data is downloaded data

如果 in 中填充了一个虚拟占位符图像,它就可以工作tableView:cellForRowAtIndexPath——imageView我想知道新图像是如何刷新的,是不是setNeedsDisplay要重新绘制?但是如果我不设置占位符图像,那么新图像根本不会显示。我想知道可以使用什么机制使其显示图像?

如果我使用

[cell.imageView setNeedsDisplay]

或者

[cell setNeedsDisplay];

在完成块中,它不起作用,如果我使用

[self.table reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
                            withRowAnimation:UITableViewRowAnimationAutomatic];

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

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

4

2 回答 2

14

当一个UITableViewCell'-layoutSubviews方法被调用时,如果它imageView的 'image属性是nilimageView则被赋予一个(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];
                                            }];

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

希望这可以帮助!

于 2012-08-31T06:17:24.393 回答
0

这不会直接回答您的问题,但是解决您的问题的一个简单解决方法是在您的文件中使用SDWebImagecellForRowAtIndexPath:。他们的 README 页面上的示例完全符合您的要求。

于 2012-08-31T05:35:33.993 回答