我正在尝试使用多线程在UITableViewCell中下载图像。但是,当我使用模拟器查看结果时,在滚动表视图之前无法加载图像。
我在StackOverFlow中观看了很多示例和教程,但它仍然无法正常工作。实际上,我从Flickr服务器下载图像并将它们存储到缓存的字典中。但我仍然可以第一次加载图像,除非我滚动表格视图并且图像开始出现。
这是我的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
NSString *cellIdentifier = [NSString stringWithFormat:@"cell%ld", (long)indexPath.row];
NSDictionary *photo = self.recentPhotos [indexPath.row];
NSString *title = [photo valueForKeyPath:FLICKR_PHOTO_TITLE];
cell.textLabel.text = title;
[cell.textLabel setFont:[UIFont fontWithName:@"OpenSans" size:18]];
if ([self.cashedImages objectForKey:cellIdentifier] != nil) {
cell.imageView.image = [self.cashedImages objectForKey:cellIdentifier];
}
else
{
dispatch_queue_t queue = dispatch_queue_create("fetch photos", 0);
dispatch_async(queue, ^{
NSURL *imageURL = [FlickrFetcher URLforPhoto:photo format:FlickrPhotoFormatSquare];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([tableView indexPathForCell:cell].row == indexPath.row) {
[self.cashedImages setValue:image forKey:cellIdentifier];
cell.imageView.image = [self.cashedImages valueForKey:cellIdentifier];
}
});
});
}
return cell;
}
答案 0 :(得分:1)
对于此任务,最好使用库。通常我使用的SDWebImage非常易于使用,并且还可以处理图像兑现。
https://github.com/rs/SDWebImage
一个例子可能是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] ;
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
}
编辑:
如果要先下载所有图像并缓存它们,则不应在tableviewCell中处理此图像。 TableViewCells将在创建时开始下载 - >当它们变得可见时。
SDWebImageView兑现之前下载的图像,因此尝试在viewDidLoad方法中添加此代码:
for (NSURL* url in self.recentPhotos) {
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:url options:SDWebImageContinueInBackground progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
//Your code if needed
}];
}
SDWebImage根据图像的绝对URL路径缓存图像。
答案 1 :(得分:1)
注意! GDImageLoader now(2016)拥有完整,超棒的Swift版本。它几乎每天都在维护 - 它可能是iOS中最重要且最基本的完美库。直到Apple明智地包含缓存,它基本上都是必须使用的库。
GDImageLoader非常简单,坚固 - 它是最好的..
https://github.com/AndreyLunevich/DLImageLoader-iOS/tree/master/DLImageLoader
没有手动,没有学习曲线 - 一个命令。完全太棒了。
-(UICollectionViewCell *)collectionView:(UICollectionView *)cv
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger thisRow = indexPath.row;
MeetingsCell *cell;
cell = [cv dequeueReusableCellWithReuseIdentifier:
@"CellPlayersB2" forIndexPath:indexPath];
cell.layer.shouldRasterize = YES; // TYPICALLY NEEDED ON iPhone6+
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
NSDictionary *mtg = CLOUD.players[thisRow];
NSString *hostText = mtg[@"host"]; etc...
cell.whenDescrip.text = etc ...;
NSString *imUrl = mtg[@"image"];
__weak UIBookView *loadBooky = cell.booky;
[DLImageLoader loadImageFromURL:imUrl
completed:^(NSError *error, NSData *imgData)
{
if (loadBooky == nil) return;
[loadBooky use:[UIImage imageWithData:imgData]];
}];
return cell;
}
答案 2 :(得分:0)
表格可能不会重新绘制内容。一个修复可能是将图像保存在self.cashedImaged(你知道这是一个错字,对吧;)),然后指示UITableView使用reloadRowsAtIndexPaths重新加载单个单元格:
答案 3 :(得分:0)
我认为最好在UIImageView上添加一个类别,并添加一个链接此方法的方法:
@interface UIImageView (Caching)
- (void)setImageWithFlickrURL:(NSURL *)url;
@end
并将您的缓存逻辑放在那里。 然后在你的cellForRow:indexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
NSURL *imageURL = [FlickrFetcher URLforPhoto:photo format:FlickrPhotoFormatSquare];
[cell.imageView setImageWithFlickrURL:imageURL];
return cell;
}
或者,您可以使用提供AFNetworking UIImageView+AFNetworking
- (void)setImageWithURL:(NSURL *)url;
答案 4 :(得分:0)
您需要添加一行:
cell.imageView.image = [self.cashedImages valueForKey:cellIdentifier];
//add this line to make tableview redraw
[cell setNeedsLayout];