- </pre><pre name="code" class="objc">
- </pre><pre name="code" class="objc">
- 在前面的一篇博客中,我写了一个瀑布流照片墙的程序,由于之前的程序加载的图片是本地的,所以在这篇文章中我来补上有关异步加载网络图片的代码,来实现之前程序的效果,希望大家批评指正呀!
这个程序中大部分的代码和之前的博客中贴出来的相同,不同的只是添加了图片缓存机制,图片异步下载线程函数,以及图片点击浏览的功能。
接下来看一下代码实现部分:
- #import "MyScrollView.h"
- #define COORDINATE_X_LEFT 5
- #define COORDINATE_X_MIDDLE MY_WIDTH/3 + 5
- #define COORDINATE_X_RIGHT MY_WIDTH/3 * 2 + 5
- #define PAGESIZE 21
- @interface MyScrollView ()
- @end
- @implementation MyScrollView
- @synthesize isOnce = _isOnce;
- @synthesize imagesName = _imagesName;
- @synthesize loadedImageDic = _loadedImageDic;
- @synthesize leftColumHeight = _leftColumHeight;
- @synthesize midColumHeight = _midColumHeight;
- @synthesize rightColumHeight = _rightColumHeight;
- @synthesize loadedImageArray = _loadedImageArray;
- @synthesize imgTag = _imgTag;
- @synthesize imgTagDic = _imgTagDic;
- @synthesize imageLoad = _imageLoad;
- @synthesize page = _page;
- @synthesize fileUtil = _fileUtil;
- @synthesize imageCache = _imageCache;
- @synthesize photoArray = _photoArray;
- //@synthesize aDelegaet;
- + (MyScrollView *)shareInstance{
- static MyScrollView *instance;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[self alloc] initWithFrame:CGRectMake(0, 0, MY_WIDTH, MY_HEIGHT)];
- });
- return instance;
- }
- /*
- 初始化scrollView的委托以及背景颜色,不显示它的水平,垂直显示条
- */
- - (id)initWithFrame:(CGRect)frame{
- self = [super initWithFrame:frame];
- if(self){
- self.delegate = self;
- self.backgroundColor = [UIColor blackColor];
- self.pagingEnabled = NO;
- self.showsHorizontalScrollIndicator = NO;
- self.showsVerticalScrollIndicator = NO;
- self.isOnce = YES;
- self.loadedImageDic = [[NSMutableDictionary alloc] init];
- self.loadedImageArray = [[NSMutableArray alloc] init];
- self.imgTagDic = [[NSMutableDictionary alloc] init];
- self.photoArray = [[NSMutableArray alloc] init];
- //初始化列的高度
- self.leftColumHeight = 3.0f;
- self.midColumHeight = 3.0f;
- self.rightColumHeight = 3.0f;
- self.imgTag = 10086;
- self.page = 1;
- self.fileUtil = [FileUtil shareInstance];
- self.imageCache = [ImageCacher shareInstance];
- _imageCache.myDelegate = self;
- [self initWithPhotoBox];
- }
- return self;
- }
- /*
- 将scrollView界面分为大小相等的3个部分,每个部分为一个UIView, 并设置每一个UIView的tag
- */
- - (void)initWithPhotoBox{
- UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, MY_WIDTH/3, self.frame.size.height)];
- UIView *middleView = [[UIView alloc] initWithFrame:CGRectMake(leftView.frame.origin.x + MY_WIDTH/3, 0, MY_WIDTH/3,
- self.frame.size.height)];
- UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(middleView.frame.origin.x + MY_WIDTH/3, 0, MY_WIDTH/3,
- self.frame.size.height)];
- //设置三个部分的tag
- leftView.tag = 100;
- middleView.tag = 101;
- rightView.tag = 102;
- //设置背景颜色
- [leftView setBackgroundColor:[UIColor clearColor]];
- [middleView setBackgroundColor:[UIColor clearColor]];
- [rightView setBackgroundColor:[UIColor clearColor]];
- [self addSubview:leftView];
- [self addSubview:middleView];
- [self addSubview:rightView];
- self.imageLoad = [ImageLoader shareInstance];
- [_imageLoad loadImage:nil];
- //第一次加载图片
- for(int i = 0; i < PAGESIZE; i++){
- NSString *imageName = [_imageLoad.imagesArray objectAtIndex:i];
- [self imageStartLoading:imageName];
- }
- //当前为第一页
- self.page = 1;
- }
- /*
- * @brief 图片加载通用函数
- * @parma imageName 图片名
- */
- - (void)imageStartLoading:(NSString *)imageName{
- NSURL *url = [NSURL URLWithString:imageName];
- if([_fileUtil hasCachedImage:url]){
- UIImageView *imageView = [[UIImageView alloc] init];
- NSString *path = [_fileUtil pathForUrl:url];
- imageView = [_imageLoad compressImage:MY_WIDTH/3 imageView:nil imageName:path flag:NO];
- [self addImage:imageView name:path];
- [self adjustContentSize:NO];
- }else{
- UIImageView *imageView = [[UIImageView alloc] init];
- NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:url, @"URL",
- imageView, @"imageView", nil nil];
- [NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:[ImageCacher shareInstance] withObject:dic];
- }
- }
- /*
- *调整scrollview
- */
- - (void)adjustContentSize:(BOOL)isEnd{
- UIView *leftView = [self viewWithTag:100];
- UIView *middleView = [self viewWithTag:101];
- UIView *rightView = [self viewWithTag:102];
- if(_leftColumHeight >= _midColumHeight && _leftColumHeight >= _rightColumHeight){
- self.contentSize = leftView.frame.size;
- }else{
- if(_midColumHeight >= _rightColumHeight){
- self.contentSize = middleView.frame.size;
- }else{
- self.contentSize = rightView.frame.size;
- }
- }
- }
- /*
- *得到最短列的高度
- */
- - (float)getTheShortColum{
- if(_leftColumHeight <= _midColumHeight && _leftColumHeight <= _rightColumHeight){
- return _leftColumHeight;
- }else{
- if(_midColumHeight <= _rightColumHeight){
- return _midColumHeight;
- }else{
- return _rightColumHeight;
- }
- }
- }
- /*
- *添加一张图片
- *规则:根据每一列的高度来决定,优先加载列高度最短的那列
- *重新设置图片的x,y坐标
- *imageView:图片视图
- *imageName:图片名
- */
- - (void)addImage:(UIImageView *)imageView name:(NSString *)imageName{
- //图片是否加载
- if([self.loadedImageDic objectForKey:imageName]){
- return;
- }
- //若图片还未加载则保存
- [self.loadedImageDic setObject:imageView forKey:imageName];
- [self.loadedImageArray addObject:imageView];
- [_photoArray addObject:imageName];
- [self imageTagWithAction:imageView name:imageName];
- float width = imageView.frame.size.width;
- float height = imageView.frame.size.height;
- //判断哪一列的高度最低
- if(_leftColumHeight <= _midColumHeight && _leftColumHeight <= _rightColumHeight){
- UIView *leftView = [self viewWithTag:100];
- [leftView addSubview:imageView];
- //重新设置坐标
- [imageView setFrame:CGRectMake(2, _leftColumHeight, width, height)];
- _leftColumHeight = _leftColumHeight + height + 3;
- [leftView setFrame:CGRectMake(0, 0, MY_WIDTH/3, _leftColumHeight)];
- }else{
- if(_midColumHeight <= _rightColumHeight){
- UIView *middleView = [self viewWithTag:101];
- [middleView addSubview:imageView];
- [imageView setFrame:CGRectMake(2, _midColumHeight, width, height)];
- _midColumHeight = _midColumHeight + height + 3;
- [middleView setFrame:CGRectMake(MY_WIDTH/3, 0, MY_WIDTH/3, _midColumHeight)];
- }else{
- UIView *rightView = [self viewWithTag:102];
- [rightView addSubview:imageView];
- [imageView setFrame:CGRectMake(2, _rightColumHeight, width, height)];
- _rightColumHeight = _rightColumHeight + height + 3;
- [rightView setFrame:CGRectMake(22 * MY_WIDTH/3, 0, MY_WIDTH/3, _rightColumHeight)];
- }
- }
- }
- /*
- 将图片tag保存,以及为UIImageView添加事件响应
- */
- - (void)imageTagWithAction:(UIImageView *)imageView name:(NSString *)imageName{
- //将要显示图片的tag保存
- imageView.tag = self.imgTag;
- [self.imgTagDic setObject:imageName forKey:[NSString stringWithFormat:@"%ld", (long)imageView.tag]];
- self.imgTag++;
- //图片添加事件响应
- UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageClickWithTag:)];
- tapRecognizer.delegate = self;
- imageView.userInteractionEnabled = YES;
- [imageView addGestureRecognizer:tapRecognizer];
- [tapRecognizer release];
- }
- /*
- //若三列中最短列距离底部高度超过30像素,则请求加载新的图片
- */
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
- //可视检查
- //[self checkImageIsVisible];
- if((self.contentOffset.y + self.frame.size.height) - [self getTheShortColum] > 30){
- [self pullRefreshImages];
- }
- }
- /*
- 上拉时加载新的图片
- */
- - (void)pullRefreshImages{
- int index = self.page *PAGESIZE;
- NSUInteger imgNum = [self.imageLoad.imagesArray count];
- if(index >= imgNum){
- //图片加载完毕
- [self adjustContentSize:YES];
- }else{
- if((imgNum - self.page*PAGESIZE) > PAGESIZE){
- for (int i = index; i < PAGESIZE; i++) {
- NSString *imageName = [_imageLoad.imagesArray objectAtIndex:i];
- [self imageStartLoading:imageName];
- }
- }else{
- for (int i = index; i < imgNum; i++) {
- NSString *imageName = [_imageLoad.imagesArray objectAtIndex:i];
- [self imageStartLoading:imageName];
- }
- }
- self.page++;
- }
- }
- /*
- 检查图片是否可见,如果不在可见视线内,则把图片替换为nil
- */
- - (void)checkImageIsVisible{
- for (int i = 0; i < [_loadedImageArray count]; i++) {
- UIImageView *imgView = [_loadedImageArray objectAtIndex:i];
- if((self.contentOffset.y - imgView.frame.origin.y) > imgView.frame.size.height ||
- imgView.frame.origin.y > (self.frame.size.height + self.contentOffset.y)){
- //不显示图片
- imgView.image = nil;
- }else{
- //重新根据tag值显示图片
- NSString *imageName = [self.imgTagDic objectForKey:[NSString stringWithFormat:@"%ld", (long)imgView.tag]];
- if((NSNull *)imageName == [NSNull null]){
- return;
- }
- UIImageView *view = [_imageLoad compressImage:MY_WIDTH/3 imageView:nil imageName:imageName flag:NO];
- imgView.image = view.image;
- }
- }
- }
- //点击图片事件响应
- - (void)imageClickWithTag:(UITapGestureRecognizer *)sender{
- UIImageView *view = (UIImageView *)sender.view;
- NSString *imageName = [self.imgTagDic objectForKey:[NSString stringWithFormat:@"%ld", (long)view.tag]];
- PhotoViewController *photoView = [[PhotoViewController alloc] init];
- photoView.imageArray = _photoArray;
- photoView.imageName = imageName;
- UIWindow *window = [[UIApplication sharedApplication].delegate window];
- [window addSubview:photoView.view];
- }
- - (void)dealloc{
- [_imagesName release];
- [_imgTagDic release];
- [_loadedImageArray release];
- [_imageCache release];
- [_fileUtil release];
- [_imageLoad release];
- [_photoArray release];
- [super dealloc];
- }
- @end
以下是ImageCacher类的代码
- #import "ImageCacher.h"
- @implementation ImageCacher
- @synthesize fileUtil = _fileUtil;
- @synthesize imageLoader = _imageLoader;
- @synthesize myDelegate = _myDelegate;
- + (ImageCacher *)shareInstance{
- static ImageCacher *instance;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[self alloc] init];
- });
- return instance;
- }
- - (id)init{
- self = [super init];
- if(self){
- self.fileUtil = [FileUtil shareInstance];
- self.imageLoader = [ImageLoader shareInstance];
- }
- return self;
- }
- - (void)cacheImage:(NSDictionary*)dic{
- NSURL *url = [dic objectForKey:@"URL"];
- NSFileManager *fileManage = [NSFileManager defaultManager];
- NSData *data = [NSData dataWithContentsOfURL:url];
- NSString *fileName = [_fileUtil pathForUrl:url];
- if(data){
- [fileManage createFileAtPath:fileName contents:data attributes:nil];
- }
- UIImageView *imageView = [dic objectForKey:@"imageView"];
- imageView.image = [UIImage imageWithData:data];
- imageView = [_imageLoader compressImage:MY_WIDTH/3 imageView:imageView imageName:nil flag:YES];
- [self.myDelegate addImage:imageView name:fileName];
- [self.myDelegate adjustContentSize:NO];
- }
- - (void)dealloc{
- [super dealloc];
- }
- @end
- 由于时间的关系,详细的讲解就留到下期来说吧!