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

Eye*_*all 14 cocoa-touch objective-c ios afnetworking uicollectionview

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

我想复制该功能,但我不知道如何去做.

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

至于现在,我迭代这个列表并为我看到的每个URL启动下载.下载完成后,我将使用重新加载集合视图[self.collectionView reloadData].但是,正如你可以想象的那样,如果我有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];
}
Run Code Online (Sandbox Code Playgroud)

所以基本上,我想知道如何在显示带图像的feed时实现Instagram和类似应用程序的功能.另外,我想知道为每个单元格启动下载的好方法,当下载完成后,更新该单元格,而不是使用[reloadData]重绘整个视图

谢谢

Ama*_*mar 16

您要实现的技术称为延迟加载.由于您使用AFNetworking它将更容易在您的情况下实现这一点.您的每个集合视图单元都需要具有UIImageView显示图像的功能.使用UIImageView+AFNetworking.h类别并通过调用方法设置正确的图像URL

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

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

    // ...
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

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

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

另外,对于您的参考,如果您想自己实现延迟加载图像,请遵循此Apple示例代码.这是为了UITableView同样的技术也可以使用UICollectionView.

希望有所帮助!