在上一篇博客中,我们实现了异步加载图片的功能,由于上次的时间问题,讲的比较简单所以在这篇文章中,我对前面代码中涉及到得关键代码再做一次详细的解释。
先看一个函数,
[objc]
/*
* @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];
}
}
该图片是否已经存在,如果存在则直接加载在视图中。一般OC的线程函数有三个,NSThread, Cocoa Operations,和GCD,(想要了解三者的异同点可查看:),
这里我用了比较轻量级的NSThread,detachNewThreadSelector函数中所传的函数名:cacheImage是类ImageCache中得函数,这里通过iOS开发中使用的比较多的单例模式,
得到了ImageCache的句柄,参数dic中主要存放了图片的网络地址以及imageView用来add图片进视图以及根据图片的大小压缩成合适的大小.
接下来是cacheImage函数:
[objc]
- (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];
}
图片显示就不会出现不全或失真的现象。由于ImageCache和MyScrollView是两个独立的类,所以这里通过使用ios的delegate(代理)来进行图片在scrollView上的加载,
(什么是代理模式:).
下面我们来看如何在沙盒中建立缓存文件夹,其实缓存文件夹跟普通的文件夹一样,只是该文件夹是专门用来存放缓存文件的而已。类代码如下所示:
[objc]
//
// FileUtil.m
// Test515
//
// Created by silicon on 14-5-30.
// Copyright (c) 2014年 silicon. All rights reserved.
//
#import "FileUtil.h"
@implementation FileUtil
+ (FileUtil *)shareInstance{
static FileUtil *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
/*
@breif 创建缓存文件夹
*/
- (void)createPathInDocumentDirectory{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];
NSLog(@"%@", diskCachePath);
if(![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]){
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:&error];
}
}
/*
@breif 获取沙盒中文档目录
@param fileName:文件名字
*/
- (NSString *)pathInDocumentDirectory:(NSString *)fileName{
NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *cacheDirectory = [fileArray objectAtIndex:0];
return [cacheDirectory stringByAppendingPathComponent:fileName];
}
/*
@breif 获取沙盒中缓存文件目录
@param fileName:文件名字
*/
- (NSString *)pathInCacheDirectory:(NSString *)fileName{
NSArray *fileArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *cacheDirectory = [fileArray objectAtIndex:0];
return [cacheDirectory stringByAppendingPathComponent:fileName];
}
/*
@breif 判断是否已经缓存
@param url:图片名称
*/
- (BOOL)hasCachedImage:(NSURL *)url{
NSFileManager *fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:[self pathForUrl:url]]){
return YES;
}else{
return NO;
}
}
/*
@breif 根据URL的給图片命名
@param url:图片url
*/
- (NSString *)pathForUrl:(NSURL *)url{
return [self pathInCacheDirectory:[NSString stringWithFormat:@"qiaoqiao-%u", [[url description] hash]]];
}
@end
手势(UITapGestureRecognizer),当用户点击图片时,程序可以根据点击视图的tag值来获得相应的图片是哪一张,从而可以加载。支持左右滑动的功能在新的界面中增加了
一个ScrollView,然后将下载下来的图片添加到scrollView中。代码如下
[objc]
//
// PhotoViewController.m
// Test515
//
// Created by silicon on 14-5-22.
// Copyright (c) 2014年 silicon. All rights reserved.
//
#import "PhotoViewController.h"
#import "ImageLoader.h"
@interface PhotoViewController ()
@end
@implementation PhotoViewController
@synthesize scrollView = _scrollView;
@synthesize imageArray = _imageArray;
@synthesize page = _page;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setFrame:CGRectMake(0, 0, MY_WIDTH, MY_HEIGHT)];
[self.view setBackgroundColor:[UIColor blackColor]];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, MY_WIDTH, MY_HEIGHT)];
_scrollView.delegate = self;
_scrollView.contentSize = CGSizeMake(MY_WIDTH * [_imageArray count], MY_HEIGHT);
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.backgroundColor = [UIColor blackColor];
_scrollView.bounces = YES;
_scrollView.pagingEnabled = YES;
[self.view addSubview:_scrollView];
//图片添加事件响应
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closePhotoView)];
tapRecognizer.delegate = self;
_scrollView.userInteractionEnabled = YES;
[_scrollView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
[self loadingImages];
}
- (void)viewWillAppear:(BOOL)animated{
[_scrollView setContentOffset:CGPointMake([_imageArray indexOfObject:_imageName] * MY_WIDTH, 0)];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//关闭
- (void)closePhotoView{
[self.view removeFromSuperview];
}
- (void)dealloc{
[_scrollView release];
[super dealloc];
}
- (void)loadingImages{
//加载图片
for(int i = 0; i < [_imageArray count]; i++){
NSString *picName = [_imageArray objectAtIndex:i];
UIImageView *imageV = [[ImageLoader shareInstance] compressImage:MY_WIDTH imageView:nil imageName:picName flag:NO];
float width = imageV.image.size.width;
float height = imageV.image.size.height;
float new_width = MY_WIDTH;
float new_height = (MY_WIDTH * height)/width;
imageV.frame = CGRectMake(MY_WIDTH * i, 0, new_width, new_height);
[_scrollView addSubview:imageV];
[imageV release];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView{
}
@end