IOS开发之异步加载网络图片并缓存本地实现瀑布流(二)

  1. /* 
  2.  * @brief 图片加载通用函数 
  3.  * @parma imageName 图片名 
  4.  */  
  5. - (void)imageStartLoading:(NSString *)imageName{  
  6.     NSURL *url = [NSURL URLWithString:imageName];  
  7.     if([_fileUtil hasCachedImage:url]){  
  8.         UIImageView *imageView = [[UIImageView alloc] init];  
  9.         NSString *path = [_fileUtil pathForUrl:url];  
  10.         imageView = [_imageLoad compressImage:MY_WIDTH/3 imageView:nil imageName:path flag:NO];  
  11.         [self addImage:imageView name:path];  
  12.         [self adjustContentSize:NO];  
  13.     }else{  
  14.         UIImageView *imageView = [[UIImageView alloc] init];  
  15.         NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:url, @"URL",  
  16.                              imageView, @"imageView", nil nil];  
  17.         [NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:[ImageCacher shareInstance] withObject:dic];  
  18.     }  
  19. }  


这个函数的作用是为每一张网络图片开启一个下载线程,但是因为该程序用到了图片缓存的技术,所以在每次开线程下载图片的时候都会去本地缓存目录查找一下,

 

该图片是否已经存在,如果存在则直接加载在视图中。一般OC的线程函数有三个,NSThread, Cocoa Operations,和GCD,(想要了解三者的异同点可查看:点击打开链接),

这里我用了比较轻量级的NSThread,detachNewThreadSelector函数中所传的函数名: cacheImage是类ImageCache中得函数,这里通过iOS开发中使用的比较多的单例模式,

得到了ImageCache的句柄,参数dic中主要存放了图片的网络地址以及imageView用来add图片进视图以及根据图片的大小压缩成合适的大小.

 

接下来是cacheImage函数:

 

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. - (void)cacheImage:(NSDictionary*)dic{  
  2.     NSURL *url = [dic objectForKey:@"URL"];  
  3.     NSFileManager *fileManage = [NSFileManager defaultManager];  
  4.     NSData *data = [NSData dataWithContentsOfURL:url];  
  5.       
  6.     NSString *fileName = [_fileUtil pathForUrl:url];  
  7.     if(data){  
  8.         [fileManage createFileAtPath:fileName contents:data attributes:nil];  
  9.     }  
  10.       
  11.     UIImageView *imageView = [dic objectForKey:@"imageView"];  
  12.     imageView.image = [UIImage imageWithData:data];  
  13.     imageView = [_imageLoader compressImage:MY_WIDTH/3 imageView:imageView imageName:nil flag:YES];  
  14.     [self.myDelegate addImage:imageView name:fileName];  
  15.     [self.myDelegate adjustContentSize:NO];  
  16. }  


该函数用来将下载下来的图片缓存进入文件沙盒中(缓存文件可以自己定义并指定),并且按照图片的大小进行等比例压缩,固定宽度是屏幕的三分之一大小,这样一来,

 

图片显示就不会出现不全或失真的现象。由于ImageCache和MyScrollView是两个独立的类,所以这里通过使用ios的delegate(代理)来进行图片在scrollView上的加载,

(什么是代理模式:点击打开链接).

 

下面我们来看如何在沙盒中建立缓存文件夹,其实缓存文件夹跟普通的文件夹一样,只是该文件夹是专门用来存放缓存文件的而已。类代码如下所示:

 

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //  
  2. //  FileUtil.m  
  3. //  Test515  
  4. //  
  5. //  Created by silicon on 14-5-30.  
  6. //  Copyright (c) 2014年 silicon. All rights reserved.  
  7. //  
  8.   
  9. #import "FileUtil.h"  
  10.   
  11. @implementation FileUtil  
  12.   
  13. + (FileUtil *)shareInstance{  
  14.     static FileUtil *instance;  
  15.     static dispatch_once_t onceToken;  
  16.     dispatch_once(&onceToken, ^{  
  17.         instance = [[self alloc] init];  
  18.     });  
  19.       
  20.     return instance;  
  21. }  
  22.   
  23. /* 
  24.  @breif 创建缓存文件夹 
  25.  */  
  26. - (void)createPathInDocumentDirectory{  
  27.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  
  28.     NSString *diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];  
  29.     NSLog(@"%@", diskCachePath);  
  30.       
  31.     if(![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]){  
  32.         NSError *error = nil;  
  33.         [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath  
  34.                                   withIntermediateDirectories:YES  
  35.                                                    attributes:nil  
  36.                                                         error:&error];  
  37.     }  
  38. }  
  39.   
  40. /* 
  41.  @breif     获取沙盒中文档目录 
  42.  @param     fileName:文件名字 
  43.  */  
  44. - (NSString *)pathInDocumentDirectory:(NSString *)fileName{  
  45.     NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,  
  46.                                                              NSUserDomainMask, YES);  
  47.     NSString *cacheDirectory = [fileArray objectAtIndex:0];  
  48.     return [cacheDirectory stringByAppendingPathComponent:fileName];  
  49. }  
  50.   
  51. /* 
  52.  @breif     获取沙盒中缓存文件目录 
  53.  @param     fileName:文件名字 
  54.  */  
  55. - (NSString *)pathInCacheDirectory:(NSString *)fileName{  
  56.     NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,  
  57.                                                              NSUserDomainMask, YES);  
  58.     NSString *cacheDirectory = [fileArray objectAtIndex:0];  
  59.     return [cacheDirectory stringByAppendingPathComponent:fileName];  
  60. }  
  61.   
  62. /* 
  63.  @breif     判断是否已经缓存 
  64.  @param     url:图片名称 
  65.  */  
  66. - (BOOL)hasCachedImage:(NSURL *)url{  
  67.     NSFileManager *fileManager = [NSFileManager defaultManager];  
  68.     if([fileManager fileExistsAtPath:[self pathForUrl:url]]){  
  69.         return YES;  
  70.     }else{  
  71.         return NO;  
  72.     }  
  73. }  
  74.   
  75. /* 
  76.  @breif     根据URL的給图片命名 
  77.  @param     url:图片url 
  78.  */  
  79. - (NSString *)pathForUrl:(NSURL *)url{  
  80.     return [self pathInCacheDirectory:[NSString stringWithFormat:@"qiaoqiao-%u", [[url description] hash]]];  
  81. }  
  82.   
  83. @end  


在这次的demo中,我新加入了用户可以点击图片放大 并可以左右滑动的功能,其实实现起来很简单,我一开始为每一个ScrollView 中得ImageView都设置了tag值,并且添加了

 

手势(UITapGestureRecognizer),当用户点击图片时,程序可以根据点击视图的tag值来获得相应的图片是哪一张,从而可以加载。支持左右滑动的功能在新的界面中增加了

一个ScrollView,然后将下载下来的图片添加到scrollView中。代码如下

 

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
    1. //  
    2. //  PhotoViewController.m  
    3. //  Test515  
    4. //  
    5. //  Created by silicon on 14-5-22.  
    6. //  Copyright (c) 2014年 silicon. All rights reserved.  
    7. //  
    8.   
    9. #import "PhotoViewController.h"  
    10. #import "ImageLoader.h"  
    11.   
    12. @interface PhotoViewController ()  
    13.   
    14. @end  
    15.   
    16. @implementation PhotoViewController  
    17. @synthesize scrollView = _scrollView;  
    18. @synthesize imageArray = _imageArray;  
    19. @synthesize page = _page;  
    20.   
    21. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
    22. {  
    23.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
    24.     if (self) {  
    25.         // Custom initialization  
    26.     }  
    27.     return self;  
    28. }  
    29.   
    30. - (void)viewDidLoad  
    31. {  
    32.     [super viewDidLoad];  
    33.     // Do any additional setup after loading the view.  
    34.     [self.view setFrame:CGRectMake(0, 0, MY_WIDTH, MY_HEIGHT)];  
    35.     [self.view setBackgroundColor:[UIColor blackColor]];  
    36.       
    37.     self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, MY_WIDTH, MY_HEIGHT)];  
    38.     _scrollView.delegate = self;  
    39.     _scrollView.contentSize = CGSizeMake(MY_WIDTH * [_imageArray count], MY_HEIGHT);  
    40.     _scrollView.showsVerticalScrollIndicator = NO;  
    41.     _scrollView.showsHorizontalScrollIndicator = NO;  
    42.     _scrollView.backgroundColor = [UIColor blackColor];  
    43.     _scrollView.bounces = YES;  
    44.     _scrollView.pagingEnabled = YES;  
    45.     [self.view addSubview:_scrollView];  
    46.       
    47.     //图片添加事件响应  
    48.     UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closePhotoView)];  
    49.     tapRecognizer.delegate = self;  
    50.     _scrollView.userInteractionEnabled = YES;  
    51.     [_scrollView addGestureRecognizer:tapRecognizer];  
    52.     [tapRecognizer release];  
    53.       
    54.     [self loadingImages];  
    55. }  
    56.   
    57. - (void)viewWillAppear:(BOOL)animated{  
    58.     [_scrollView setContentOffset:CGPointMake([_imageArray indexOfObject:_imageName] * MY_WIDTH, 0)];  
    59. }  
    60.   
    61. - (void)didReceiveMemoryWarning  
    62. {  
    63.     [super didReceiveMemoryWarning];  
    64.     // Dispose of any resources that can be recreated.  
    65. }  
    66.   
    67. //关闭  
    68. - (void)closePhotoView{  
    69.     [self.view removeFromSuperview];  
    70. }  
    71.   
    72. - (void)dealloc{  
    73.     [_scrollView release];  
    74.     [super dealloc];  
    75. }  
    76.   
    77. - (void)loadingImages{  
    78.     //加载图片  
    79.     for(int i = 0; i < [_imageArray count]; i++){  
    80.         NSString *picName = [_imageArray objectAtIndex:i];  
    81.         UIImageView *imageV = [[ImageLoader shareInstance] compressImage:MY_WIDTH imageView:nil imageName:picName flag:NO];  
    82.           
    83.         float width = imageV.image.size.width;  
    84.         float height = imageV.image.size.height;  
    85.           
    86.         float new_width = MY_WIDTH;  
    87.         float new_height = (MY_WIDTH * height)/width;  
    88.           
    89.         imageV.frame = CGRectMake(MY_WIDTH * i, 0, new_width, new_height);  
    90.         [_scrollView addSubview:imageV];  
    91.         [imageV release];  
    92.     }  
    93. }  
    94.   
    95. - (void)scrollViewDidScroll:(UIScrollView *)_scrollView{  
    96.   
    97. }  
    98.   
    99. @end  
posted @ 2016-08-12 08:56  Jack~Bai  阅读(1038)  评论(0编辑  收藏  举报