使用异步读取从服务器获取数据,并在的CollectionView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
YourDataModel *model = self.dataArray[indexPath.row];
YourCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
if ([self checkWhetherImageAlreadyExist]) {
[cell.imageView setImage:model.image];
} else {
//show placeholder to avoid nothing in your UI, or your user gets confused
[cell.imageView setImage:placeholderImage];
[self startDownloadImageForIndexPath:indexPath];
}
}
- (void)startDownloadImageForIndexPath:(NSIndexPath *)indexPath
{
//YourImageDownloader is a class to fetch data from server
//imageDownloadsInProgress is a NSMutableDictionary to record the download process, which can avoid repeat download
YourImageDownloader *downloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (downloader == nil) {
YourDataModel *model = self.dataArray[indexPath.row];
//configure downloader
downloader = [[YourImageDownloader alloc] init];
[downloader setURL:model.url];
[downloader setCompletionHandler:^{
//download the image to local, or you can pass the image to the block
model.image = [UIImage imageWithContentsOfFile:model.localPath];
YourCell *cell = [self.mCollectionView cellForItemAtIndexPath:indexPath];
[cell.imageView setImage:model.image];
//remove downloader from dictionary
[self.imageDownloadsInProgress removeObjectForKey:indexPath];
}];
//add downloader to dictionary
[self.imageDownloadsInProgress setObject:downloader forKey:indexPath];
//start download
[downloader startDownload];
}
}
显示它使用一个类来下载图像。如果您在一个集合视图中有多个图像,则可能会考虑将这些图像保存到本地以防内存警告。如果现在很多,只需将图像留在内存中并将其显示在收藏视图中。
接下来的代码是将图像保存到本地,并在显示时从本地读取图像数据。
in。H:
#import <Foundation/Foundation.h>
@interface PortraitDownloader : NSObject
@property (nonatomic, copy) NSString *portraitName;
@property (nonatomic, copy) void (^completionHandler)(void);
- (void)startDownload;
- (void)cancelDownload;
@end
在.M
#import "PortraitDownloader.h"
#import <CFNetwork/CFNetwork.h>
#import "NSString+ImagePath.h" // it's a category to get the image local path
@interface PortraitDownloader()
@property (nonatomic, strong) NSMutableData *activeDownload;
@property (nonatomic, strong) NSURLConnection *portraitConnection;
@end
@implementation PortraitDownloader
- (void)startDownload
{
self.activeDownload = [NSMutableData data];
NSString *urlstr = [NSString serverPortraitPathWithPortrait:self.portraitName];
NSURL *url = [NSURL URLWithString:urlstr];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
self.portraitConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)cancelDownload
{
[self.portraitConnection cancel];
self.portraitConnection = nil;
self.activeDownload = nil;
}
#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.activeDownload appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// Clear the activeDownload property to allow later attempts
self.activeDownload = nil;
// Release the connection now that it's finished
self.portraitConnection = nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// save to local path
NSString *localSavePath = [NSString localPortraitPathWithPortrait:self.portraitName];
[self.activeDownload writeToFile:localSavePath atomically:YES];
self.activeDownload = nil;
// Release the connection now that it's finished
self.portraitConnection = nil;
// call our delegate and tell it that our icon is ready for display
if (self.completionHandler) {
self.completionHandler();
}
}
@end
如果你想留在内存中的图像,只修改完成块为:
在.H
typedef void (^Completion_handle) (UIImage *image);
@interface PortraitDownloader : NSObject
@property (nonatomic, copy) Completion_handle myCompletionBlock;
and in .m
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// get image from data
UIImage *image = [UIImage imageWithData:self.activeDownload];
self.activeDownload = nil;
// Release the connection now that it's finished
self.portraitConnection = nil;
// call our delegate and tell it that our icon is ready for display
if (self.myCompletionBlock) {
self.myCompletionBlock(image);
}
}
,并修改方法startDownloadImageForIndexPath,将图像保存到你的模型把它保留下来
感谢您的工作。它帮助我很多。 – Mehdi