ios - UICollectionView - 下载图像和有效地重新加载数据,如 Instagram

标签 ios objective-c cocoa-touch afnetworking uicollectionview

我注意到像 Intagram 这样的应用程序使用 UICollectionViews 来显示照片提要。 我还注意到,这些照片的单元格在实际照片完全下载之前以某种方式放置在屏幕上。然后,当下载完成时,该照片会很好地显示在正确的单元格中。

我想复制那个功能,但我不知道该怎么做。

我目前正在下载一个大型 JSON 对象,我将其转换为一个 NSDictionaries 数组。每个 NSDictionary 都包含有关每张照片的信息,在这些信息中,会显示一个 URL。在这个 URL 中,我可以找到我需要下载并显示在我的 UICollectionViewCells

中的相应图像

至于现在,我迭代此列表并为我看到的每个 URL 启动下载。下载完成后,我使用 [self.collectionView reloadData] 重新加载 collectionview。但是,正如您可以想象的那样,如果我有 30 个单元都需要图像,就会有很多 reloadData 调用。

我正在使用 AFNetworking 来处理下载,这是我根据之前提到的 URL 调用的方法:

-(void) downloadFeedImages:(NSString *) photoURL imageDescs:(NSDictionary*)imageDescs photoId:(NSString *)photoID{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *directory = [paths objectAtIndex:0];

    NSString* foofile = [directory stringByAppendingPathComponent:photoID];

    if([[NSFileManager defaultManager] fileExistsAtPath:foofile]){
        // IF IMAGE IS CACHED
        [self.collectionView reloadData];
        return;
    }

    NSLog(@"photoURL: %@", photoURL);
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photoURL]];
    AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request
                                                                              imageProcessingBlock:nil
                                                                                           success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                                                                               // Save Image
                                                                                               NSLog(@"URL-RESPONSE:%@", image);
                                                                                               NSString *myFile = [directory stringByAppendingPathComponent:photoID];

                                                                                               NSData *imageData = UIImagePNGRepresentation(image);
                                                                                               [imageData writeToFile:myFile  atomically: YES];
                                                                                               [self.collectionView reloadData];
                                                                                           }
                                                                                           failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                                                                                               NSLog(@"ERROR: %@", [error localizedDescription]);
                                                                                           }];
    [[WebAPI sharedInstance] enqueueHTTPRequestOperation:operation];
}

所以 基本上,我想知道如何实现 Instagram 和类似应用程序在显示带有图像的提要时所具有的功能。 此外,我想知道一种为每个单元格启动下载的好方法,下载完成后,更新该单元格,而不是使用 [reloadData]

重绘整个 View

谢谢

最佳答案

您要实现的技术称为延迟加载。由于您使用的是 AFNetworking,因此在您的案例中实现起来会更容易。您的每个 Collection View 单元格都需要有一个 UIImageView 来显示图像。使用UIImageView+AFNetworking.h类,通过调用方法设置正确的图片URL

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // ....

    [cell.imageView setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

    // ...
    return cell;
}

占位符是在下载所需图像之前将显示的图像。这将为您完成所需的工作。

注意:默认情况下,URL 请求的缓存策略为NSURLCacheStorageAllowed,超时间隔为 30 秒,并且设置为不处理 cookie。要以不同方式配置 URL 请求,请使用 setImageWithURLRequest:placeholderImage:success:failure:

另外,供大家引用,如果想自己实现图片延迟加载,可以按这个Apple sample code .这适用于 UITableView,但同样的技术也可用于 UICollectionView

希望对您有所帮助!

关于ios - UICollectionView - 下载图像和有效地重新加载数据,如 Instagram,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18458934/

相关文章:

ios - 用 3 个图像构建一个 UIButton

ios - 检测何时启用 localVideoTrack false WebRTC IOS

objective-c - iPad 模拟器和设备之间 NSDateFormatter 的区别

ios - 从 swift 到 Objective C 的 NSDictionary 问题

iphone - 从 app1 启动 app2 并传递数据

cocoa - NSXMLParser 数据所有权

objective-c - 结合 UIWindows?

iOS 如何将逗号分隔的 Array 对象转换为字符串?

objective-c - UITextView textviewshouldendediting 从未调用过

ios - 为每个线程创建EAGLContext可以吗?