独角兽企业重金招聘Python工程师标准>>>
版权声明:本文为博主原创文章,未经博主允许。
[objc]view plaincopy
</pre><prename="code"class="objc">
[objc]view plaincopy
</pre><prename="code"class="objc">
[objc]view plaincopy
在前面的一篇博客中,我写了一个瀑布流照片墙的程序,由于之前的程序加载的图片是本地的,所以在这篇文章中我来补上有关异步加载网络图片的代码,来实现之前程序的效果,希望大家批评指正呀!
这个程序中大部分的代码和之前的博客中贴出来的相同,不同的只是添加了图片缓存机制,图片异步下载线程函数,以及图片点击浏览的功能。
接下来看一下代码实现部分:
[objc]view plaincopy
#import"MyScrollView.h"
#defineCOORDINATE_X_LEFT5
#defineCOORDINATE_X_MIDDLEMY_WIDTH/3+5
#defineCOORDINATE_X_RIGHTMY_WIDTH/3*2+5
#definePAGESIZE21
@interface MyScrollView()
@end
@implementationMyScrollView
@synthesizeisOnce=_isOnce;
@synthesizeimagesName=_imagesName;
@synthesizeloadedImageDic=_loadedImageDic;
@synthesizeleftColumHeight=_leftColumHeight;
@synthesizemidColumHeight=_midColumHeight;
@synthesizerightColumHeight=_rightColumHeight;
@synthesizeloadedImageArray=_loadedImageArray;
@synthesizeimgTag=_imgTag;
@synthesizeimgTagDic=_imgTagDic;
@synthesizeimageLoad=_imageLoad;
@synthesizepage=_page;
@synthesizefileUtil=_fileUtil;
@synthesizeimageCache=_imageCache;
@synthesizephotoArray=_photoArray;
//@synthesizeaDelegaet;
+(MyScrollView*)shareInstance{
staticMyScrollView*instance;
staticdispatch_once_tonceToken;
dispatch_once(&onceToken,^{
instance=[[selfalloc]initWithFrame:CGRectMake(0,0,MY_WIDTH,MY_HEIGHT)];
});
returninstance;
}
/*
初始化scrollView的委托以及背景颜色,不显示它的水平,垂直显示条
*/
-(id)initWithFrame:(CGRect)frame{
self=[superinitWithFrame:frame];
if(self){
self.delegate=self;
self.backgroundColor=[UIColorblackColor];
self.pagingEnabled=NO;
self.showsHorizontalScrollIndicator=NO;
self.showsVerticalScrollIndicator=NO;
self.isOnce=YES;
self.loadedImageDic=[[NSMutableDictionaryalloc]init];
self.loadedImageArray=[[NSMutableArrayalloc]init];
self.imgTagDic=[[NSMutableDictionaryalloc]init];
self.photoArray=[[NSMutableArrayalloc]init];
//初始化列的高度
self.leftColumHeight=3.0f;
self.midColumHeight=3.0f;
self.rightColumHeight=3.0f;
self.imgTag=10086;
self.page=1;
self.fileUtil=[FileUtilshareInstance];
self.imageCache=[ImageCachershareInstance];
_imageCache.myDelegate=self;
[selfinitWithPhotoBox];
}
returnself;
}
/*
将scrollView界面分为大小相等的3个部分,每个部分为一个UIView,并设置每一个UIView的tag
*/
-(void)initWithPhotoBox{
UIView*leftView=[[UIViewalloc]initWithFrame:CGRectMake(0,0,MY_WIDTH/3,self.frame.size.height)];
UIView*middleView=[[UIViewalloc]initWithFrame:CGRectMake(leftView.frame.origin.x+MY_WIDTH/3,0,MY_WIDTH/3,
self.frame.size.height)];
UIView*rightView=[[UIViewalloc]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;
//设置背景颜色
[leftViewsetBackgroundColor:[UIColorclearColor]];
[middleViewsetBackgroundColor:[UIColorclearColor]];
[rightViewsetBackgroundColor:[UIColorclearColor]];
[selfaddSubview:leftView];
[selfaddSubview:middleView];
[selfaddSubview:rightView];
self.imageLoad=[ImageLoadershareInstance];
[_imageLoadloadImage:nil];
//第一次加载图片
for(inti=0;i<PAGESIZE;i++){
NSString*imageName=[_imageLoad.imagesArrayobjectAtIndex:i];
[selfimageStartLoading:imageName];
}
//当前为第一页
self.page=1;
}
/*
*@brief图片加载通用函数
*@parmaimageName图片名
*/
-(void)imageStartLoading:(NSString*)imageName{
NSURL*url=[NSURLURLWithString:imageName];
if([_fileUtilhasCachedImage:url]){
UIImageView*imageView=[[UIImageViewalloc]init];
NSString*path=[_fileUtilpathForUrl:url];
imageView=[_imageLoadcompressImage:MY_WIDTH/3imageView:nilimageName:pathflag:NO];
[selfaddImage:imageViewname:path];
[selfadjustContentSize:NO];
}else{
UIImageView*imageView=[[UIImageViewalloc]init];
NSDictionary*dic=[NSDictionarydictionaryWithObjectsAndKeys:url,@"URL",
imageView,@"imageView",nilnil];
[NSThreaddetachNewThreadSelector:@selector(cacheImage:)toTarget:[ImageCachershareInstance]withObject:dic];
}
}
/*
*调整scrollview
*/
-(void)adjustContentSize:(BOOL)isEnd{
UIView*leftView=[selfviewWithTag:100];
UIView*middleView=[selfviewWithTag:101];
UIView*rightView=[selfviewWithTag: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*)imageViewname:(NSString*)imageName{
//图片是否加载
if([self.loadedImageDicobjectForKey:imageName]){
return;
}
//若图片还未加载则保存
[self.loadedImageDicsetObject:imageViewforKey:imageName];
[self.loadedImageArrayaddObject:imageView];
[_photoArrayaddObject:imageName];
[selfimageTagWithAction:imageViewname:imageName];
floatwidth=imageView.frame.size.width;
floatheight=imageView.frame.size.height;
//判断哪一列的高度最低
if(_leftColumHeight<=_midColumHeight&&_leftColumHeight<=_rightColumHeight){
UIView*leftView=[selfviewWithTag:100];
[leftViewaddSubview:imageView];
//重新设置坐标
[imageViewsetFrame:CGRectMake(2,_leftColumHeight,width,height)];
_leftColumHeight=_leftColumHeight+height+3;
[leftViewsetFrame:CGRectMake(0,0,MY_WIDTH/3,_leftColumHeight)];
}else{
if(_midColumHeight<=_rightColumHeight){
UIView*middleView=[selfviewWithTag:101];
[middleViewaddSubview:imageView];
[imageViewsetFrame:CGRectMake(2,_midColumHeight,width,height)];
_midColumHeight=_midColumHeight+height+3;
[middleViewsetFrame:CGRectMake(MY_WIDTH/3,0,MY_WIDTH/3,_midColumHeight)];
}else{
UIView*rightView=[selfviewWithTag:102];
[rightViewaddSubview:imageView];
[imageViewsetFrame:CGRectMake(2,_rightColumHeight,width,height)];
_rightColumHeight=_rightColumHeight+height+3;
[rightViewsetFrame:CGRectMake(22*MY_WIDTH/3,0,MY_WIDTH/3,_rightColumHeight)];
}
}
}
/*
将图片tag保存,以及为UIImageView添加事件响应
*/
-(void)imageTagWithAction:(UIImageView*)imageViewname:(NSString*)imageName{
//将要显示图片的tag保存
imageView.tag=self.imgTag;
[self.imgTagDicsetObject:imageNameforKey:[NSStringstringWithFormat:@"%ld",(long)imageView.tag]];
self.imgTag++;
//图片添加事件响应
UITapGestureRecognizer*tapRecognizer=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(imageClickWithTag:)];
tapRecognizer.delegate=self;
imageView.userInteractionEnabled=YES;
[imageViewaddGestureRecognizer:tapRecognizer];
[tapRecognizerrelease];
}
/*
//若三列中最短列距离底部高度超过30像素,则请求加载新的图片
*/
-(void)scrollViewDidScroll:(UIScrollView*)scrollView{
//可视检查
//[selfcheckImageIsVisible];
if((self.contentOffset.y+self.frame.size.height)-[selfgetTheShortColum]>30){
[selfpullRefreshImages];
}
}
/*
上拉时加载新的图片
*/
-(void)pullRefreshImages{
intindex=self.page*PAGESIZE;
NSUIntegerimgNum=[self.imageLoad.imagesArraycount];
if(index>=imgNum){
//图片加载完毕
[selfadjustContentSize:YES];
}else{
if((imgNum-self.page*PAGESIZE)>PAGESIZE){
for(inti=index;i<PAGESIZE;i++){
NSString*imageName=[_imageLoad.imagesArrayobjectAtIndex:i];
[selfimageStartLoading:imageName];
}
}else{
for(inti=index;i<imgNum;i++){
NSString*imageName=[_imageLoad.imagesArrayobjectAtIndex:i];
[selfimageStartLoading:imageName];
}
}
self.page++;
}
}
/*
检查图片是否可见,如果不在可见视线内,则把图片替换为nil
*/
-(void)checkImageIsVisible{
for(inti=0;i<[_loadedImageArraycount];i++){
UIImageView*imgView=[_loadedImageArrayobjectAtIndex: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.imgTagDicobjectForKey:[NSStringstringWithFormat:@"%ld",(long)imgView.tag]];
if((NSNull*)imageName==[NSNullnull]){
return;
}
UIImageView*view=[_imageLoadcompressImage:MY_WIDTH/3imageView:nilimageName:imageNameflag:NO];
imgView.image=view.image;
}
}
}
//点击图片事件响应
-(void)imageClickWithTag:(UITapGestureRecognizer*)sender{
UIImageView*view=(UIImageView*)sender.view;
NSString*imageName=[self.imgTagDicobjectForKey:[NSStringstringWithFormat:@"%ld",(long)view.tag]];
PhotoViewController*photoView=[[PhotoViewControlleralloc]init];
photoView.imageArray=_photoArray;
photoView.imageName=imageName;
UIWindow*window=[[UIApplicationsharedApplication].delegatewindow];
[windowaddSubview:photoView.view];
}
-(void)dealloc{
[_imagesNamerelease];
[_imgTagDicrelease];
[_loadedImageArrayrelease];
[_imageCacherelease];
[_fileUtilrelease];
[_imageLoadrelease];
[_photoArrayrelease];
[superdealloc];
}
@end
当程序第一次加载或者下拉刷新时,就开始下载图片,函数:imageStartLoading用于下载图片,该函数为每一次下载图片都开启一个线程,在ImageCacher类中有cacheImage函数,用于判断该图片是否已经存在本地,并且将图片放入到视图中去。
以下是ImageCacher类的代码
[objc]view plaincopy
#import"ImageCacher.h"
@implementationImageCacher
@synthesizefileUtil=_fileUtil;
@synthesizeimageLoader=_imageLoader;
@synthesizemyDelegate=_myDelegate;
+(ImageCacher*)shareInstance{
staticImageCacher*instance;
staticdispatch_once_tonceToken;
dispatch_once(&onceToken,^{
instance=[[selfalloc]init];
});
returninstance;
}
-(id)init{
self=[superinit];
if(self){
self.fileUtil=[FileUtilshareInstance];
self.imageLoader=[ImageLoadershareInstance];
}
returnself;
}
-(void)cacheImage:(NSDictionary*)dic{
NSURL*url=[dicobjectForKey:@"URL"];
NSFileManager*fileManage=[NSFileManagerdefaultManager];
NSData*data=[NSDatadataWithContentsOfURL:url];
NSString*fileName=[_fileUtilpathForUrl:url];
if(data){
[fileManagecreateFileAtPath:fileNamecontents:dataattributes:nil];
}
UIImageView*imageView=[dicobjectForKey:@"imageView"];
imageView.image=[UIImageimageWithData:data];
imageView=[_imageLoadercompressImage:MY_WIDTH/3imageView:imageViewimageName:nilflag:YES];
[self.myDelegateaddImage:imageViewname:fileName];
[self.myDelegateadjustContentSize:NO];
}
-(void)dealloc{
[superdealloc];
}
@end
由于时间的关系,详细的讲解就留到下期来说吧!
[objc]view plaincopy
#import"ImageCacher.h"
@implementationImageCacher
@synthesizefileUtil=_fileUtil;
@synthesizeimageLoader=_imageLoader;
@synthesizemyDelegate=_myDelegate;
+(ImageCacher*)shareInstance{
staticImageCacher*instance;
staticdispatch_once_tonceToken;
dispatch_once(&onceToken,^{
instance=[[selfalloc]init];
});
returninstance;
}
-(id)init{
self=[superinit];
if(self){
self.fileUtil=[FileUtilshareInstance];
self.imageLoader=[ImageLoadershareInstance];
}
returnself;
}
-(void)cacheImage:(NSDictionary*)dic{
NSURL*url=[dicobjectForKey:@"URL"];
NSFileManager*fileManage=[NSFileManagerdefaultManager];
NSData*data=[NSDatadataWithContentsOfURL:url];
NSString*fileName=[_fileUtilpathForUrl:url];
if(data){
[fileManagecreateFileAtPath:fileNamecontents:dataattributes:nil];
}
UIImageView*imageView=[dicobjectForKey:@"imageView"];
imageView.image=[UIImageimageWithData:data];
imageView=[_imageLoadercompressImage:MY_WIDTH/3imageView:imageViewimageName:nilflag:YES];
[self.myDelegateaddImage:imageViewname:fileName];
[self.myDelegateadjustContentSize:NO];
}
-(void)dealloc{
[superdealloc];
}
@end
由于时间的关系,详细的讲解就留到下期来说吧!