在上一篇博客中,咱們實現了異步加載圖片的功能,因爲上次的時間問題,講的比較簡單因此在這篇文章中,我對前面代碼中涉及到得關鍵代碼再作一次詳細的解釋。ios
先看一個函數,緩存
[objc] view plaincopy網絡
/* 異步
* @brief 圖片加載通用函數 函數
* @parma imageName 圖片名 url
*/ spa
- (void)imageStartLoading:(NSString *)imageName{ .net
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] view plaincopy
- (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] view plaincopy
//
// 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
在此次的demo中,我新加入了用戶能夠點擊圖片放大 並能夠左右滑動的功能,其實實現起來很簡單,我一開始爲每個ScrollView 中得ImageView都設置了tag值,而且添加了
手勢(UITapGestureRecognizer),當用戶點擊圖片時,程序能夠根據點擊視圖的tag值來得到相應的圖片是哪一張,從而能夠加載。支持左右滑動的功能在新的界面中增長了
一個ScrollView,而後將下載下來的圖片添加到scrollView中。代碼以下
[objc] view plaincopy
//
// 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