zoukankan      html  css  js  c++  java
  • 图片懒加载(仿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
  • 相关阅读:
    对MVC模型的自悟,详尽解释,为了更多非计算机人员可以理解
    openSUSE leap 42.3 实现有线 无线同时用
    Fedora27 源配置
    Ubuntu16.04添加HP Laserjet Pro M128fn打印机和驱动
    openSUSE leap 42.3 添加HP Laserjet Pro M128fn打印机和驱动
    OpenSUSE Leap 42.3下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    OpenSUSE Leap 42.3 安装java(Oracle jre)
    linux下支持托盘的邮件客户端Sylpheed
    Ubuntu下通过Firefox Opera Chromium浏览器直接执行java应用程序(打开java jnlp文件)实现在服务器远程虚拟控制台完成远程管理的方法
    Firefox 浏览器添加Linux jre插件
  • 原文地址:https://www.cnblogs.com/liaods/p/4805531.html
Copyright © 2011-2022 走看看