图片懒加载(仿SDWebImage)

1.图片缓存

#import "UIImageView+WebCache.h"
#import "ImageDownloader.h"

@implementation UIImageView (WebCache)

- (void)setImageWithUrl:(NSString *)urlStr andPlaceHolderImage:(UIImage *)image andIsScrolling:(BOOL)isScroll
{
    self.image = image;
    //文件夹位置
    NSString *dirPath = [NSHomeDirectory() stringByAppendingString:@"/Library/Caches/images"];
    NSFileManager *fm = [NSFileManager defaultManager];
    //判断文件夹是否存在
    BOOL isDir = YES;
    if (![fm fileExistsAtPath:dirPath isDirectory:&isDir]) {
        //创建文件夹
        [fm createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    //取得文件名称
    NSString *fileName = [[urlStr componentsSeparatedByString:@"/"]lastObject];
    //取得文件路径
    NSString *filePath = [dirPath stringByAppendingFormat:@"/%@",fileName];
    
    //先从本地找该图片是否存在,如果存在直接从本地加载图片,否则从网络获取
    if ([fm fileExistsAtPath:filePath]) {
        self.image = [UIImage imageWithContentsOfFile:filePath];
        NSLog(@"从本地加载");
        self.layer.borderWidth = 2;
        return;
    }
    
    //如果tableview滚动,则不去加载图片
    if (isScroll) {
        return;
    }
    
    //如果该url已经存在manager中,即当前url已经对应有一个下载线程在下载该图片,则不需要再次启动线程下载该图片
    if ([[ImageDownloaderManager sharedManager]checkImageDownloaderIsExist:urlStr]) {
        return;
    }

    for (ImageDownloader *downloader in [[ImageDownloaderManager sharedManager]allDownloaders]) {
        if (downloader.imageView == self) {
            NSLog(@"----取消下载之前的!");
            [downloader cancel];
            [[ImageDownloaderManager sharedManager]removeDownloaderWithUrl:downloader.urlStr];
            break;
        }
    }
    
    self.layer.borderWidth = 0;
    NSLog(@"----新的下载");
    //从网络获取
    __weak typeof(self)wSelf = self;
    __block typeof(filePath)wFilePath = filePath;
    ImageDownloader *downloader = [[ImageDownloader alloc]init];
    downloader.imageView = self;
    //以urlstr为key值保存imagedownloader
    [[ImageDownloaderManager sharedManager]addDownloader:downloader withUrl:urlStr];
    [downloader startDownImageWithUrl:urlStr whenSuccess:^(id responseData) {
        //设置自身image为网络请求返回的数据
        wSelf.image = [UIImage imageWithData:responseData];
        wSelf.layer.borderWidth = 0;
        //本地缓存
        [((NSData *)responseData) writeToFile:wFilePath atomically:YES];
        [[ImageDownloaderManager sharedManager]removeDownloaderWithUrl:urlStr];
        NSLog(@"成功:%ld",[[ImageDownloaderManager sharedManager] count]);
    } andFailure:^(NSString *errorDesc) {
        [[ImageDownloaderManager sharedManager]removeDownloaderWithUrl:urlStr];
        
        NSLog(@"失败:%ld",[[ImageDownloaderManager sharedManager] count]);
    }];
}

@end

2.viewController实现图片懒加载

#import "ViewController.h"
#import "UIImageView+WebCache.h"

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
    UITableView *_tableView;
    NSMutableArray *_dataArr;
}
@end

// 主界面菜单
#define MAINMENU_URL @"%@/HandheldKitchen/api/more/tblcalendaralertinfo!getHomePage.do?phonetype=2&page=1&pageRecord=30&user_id=&is_traditional=0"
//最新主机地址和端口
#define kHost_And_Port @"http://121.40.54.251:80"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];
    
    //请求网络数据
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        _dataArr = [[NSMutableArray alloc]init];
        
        NSString *urlStr = [NSString stringWithFormat:MAINMENU_URL,kHost_And_Port];
        //同步网络请求
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlStr]];
        if (data) {
            //解析数据
            NSDictionary *rootDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            for (NSDictionary *dic in rootDic[@"data"]) {
                [_dataArr addObject:dic[@"imagePathLandscape"]];
            }
            
            //主线程刷新
            dispatch_async(dispatch_get_main_queue(), ^{
                [_tableView reloadData];
            });
        }
    });
}

#pragma mark -TableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIde = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIde];
    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIde];
        //添加imgView
        UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(200, 5, 80, 80)];
        [cell.contentView addSubview:imgView];
        imgView.tag = 100;
        
        if (indexPath.row == 0) {
            cell.backgroundColor = [UIColor redColor];
        }
    }
    UIImageView *imgView = (UIImageView *)[cell.contentView viewWithTag:100];
    
    //isDecelerating是否减速中,isDragging是否被拖拽中,满足其中一个,则tableview没有静止
    [imgView setImageWithUrl:_dataArr[indexPath.row] andPlaceHolderImage:[UIImage imageNamed:@"1.png"] andIsScrolling:_tableView.isDecelerating || _tableView.isDragging];
    
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld个",indexPath.row];
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 90;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //tableview静止,加载图片
    [self downloadScreenCellImages];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //decelerate是否即将减速,若为yes则会出发didenddecelerate方法,否则不会,所以没有减速时需要加载当前屏幕范围内的图片
    //不存在减速即tableview已经静止
    if (!decelerate) {
        [self downloadScreenCellImages];
    }
}

//加载当前屏幕范围内可见cell的图片
- (void)downloadScreenCellImages
{
    //获取当前屏幕可见cell
    NSArray *cells = [_tableView visibleCells];
    for (UITableViewCell *cell in cells) {
        UIImageView *imgView = (UIImageView *)[cell.contentView viewWithTag:100];
        //获取cell所对应的indexpath
        NSIndexPath *indexPath = [_tableView indexPathForCell:cell];
        [imgView setImageWithUrl:_dataArr[indexPath.row] andPlaceHolderImage:[UIImage imageNamed:@"1.png"] andIsScrolling:NO];
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 

posted on 2015-09-13 20:27  Baymax01  阅读(303)  评论(0编辑  收藏  举报

导航