本帖最后由 Simpon 于 2016-10-24 09:52 编辑
原文出处:http://www.jianshu.com/p/d61ca485e5e9
【GitHub,星星啥的不需要了,对你有点启发就好】
把前两天写的两个 UIImageView 的无限轮播完善一下,主要是简单实现轮播图加载网络照片!其他的点击图片响应等慢慢实现,小伙伴们不要放弃加油,继续寻找幸福吧!
【两个 UIImageView 无限轮播图参考思路】
无限轮播_网路图片加本地.gif
思路分析:- 在原有的基础之上,初始化轮播图视图的方法中增加一个参数,告诉它传入的照片名数组是本地照片,还是网络照片!
- 在需要照片的地方判断传入的参数是否为网络照片,是的话就去获取(第一次),获取的照片缓存起来,下次使用的时候直接去缓存中获取。
- 创建一个获取网络照片的管理类,只需要传入照片的网络地址,就可以请求成功缓存起来。
- 发起网络请求之前先根据网址进行判断本地是否已经缓存了该图片。
- 缓存中有的话从缓存取出,没有则利用 Session 请求获取该图片并缓存到本地。
- 注意的是我们根据网址去判断,那么我们存储到沙盒缓存的文件名称要和网址字符串一一对应。
- 这里不能直接用网址作为文件名称,所以我考虑把网址字符串用 MD5 转化后作为文件名称存储在缓存中。
上代码:- 我们新建的获取图片的类:
PP_LoadImageManagar.h - 声明一个代理协议,获取照片时候回调给需要的类
[Objective-C] 纯文本查看 复制代码 @protocol PP_LoadImageManagarDelegate <NSObject>
//当获取到UIImage数据的时候,代理对象执行这个方法
- (void)imageDownloader:(PP_LoadImageManagar *)downloader didFinishedLoading:(UIImage *)image;
@end
定义一个回调照片的 Block类型 在不使用代理的时候使用它回调
typedef void(^PP_RturnBlock)(UIImage *returnImage); - 其它给外界的借口
[Objective-C] 纯文本查看 复制代码 // 单例创建
+ (instancetype)shareImageDownManagar;
/**
获取照片
@param imageUrlStr 照片的网址
@param dele 执行的代理 (可以为空,执行 Block 即可)
@param returnImage Block 回调传回需要的照片
*/
- (void)getImageUrlString:(NSString *)imageUrlStr delegate:(id<PP_LoadImageManagarDelegate>)dele successfulBlock:(PP_RturnBlock)returnImage;
// 清除缓存
- (void)clearLoopImageViewCaches;
PP_LoadImageManagar.m中
- 创建缓存的文件夹,返回他的路径
[Objective-C] 纯文本查看 复制代码 // 创建缓存文件夹
- (NSString *)getLocationImageDataFilePath{
// 获取 Document 路径
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 拼接一个缓存的文件夹路径
path = [path stringByAppendingPathComponent:@"PP_LoopViewCache"];
NSFileManager *mgr = [NSFileManager defaultManager];
// 是否存在文件 没有就创建
if(![mgr fileExistsAtPath:path]){
[mgr createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
return path;
} - MD5转换
[Objective-C] 纯文本查看 复制代码 // 把字符串转化成 MD5字符串 去掉特殊的标记
- (NSString *)getMD5String:(NSString *)string
{
// 转成 C 语言的字符串
const char *mdData = [string UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(mdData, (CC_LONG)strlen(mdData), result);
// 化成 OC 不可变 字符串
NSMutableString *mdString = [NSMutableString new];
for (int i =0 ; i < CC_MD5_DIGEST_LENGTH; i++)
{
[mdString appendFormat:@"%02X",result[i]];
}
return mdString;
} - 把 NSData 对象缓存本地 指定的文件夹中
[Objective-C] 纯文本查看 复制代码 - (void)writToCacheWithData:(NSData *)data subPath:(NSString *)subPath
{
// 直接写入本地
subPath = [self getMD5String:subPath];
[data writeToFile:[[self getLocationImageDataFilePath] stringByAppendingPathComponent:subPath] atomically:YES];
} - 从缓存中取出照片根据字符串网址
[Objective-C] 纯文本查看 复制代码 - (UIImage *)getImageFromSubPath:(NSString *)subPath
{
subPath = [self getMD5String:subPath];
NSData *data = [NSData dataWithContentsOfFile:[[self getLocationImageDataFilePath] stringByAppendingPathComponent:subPath]];
return [UIImage imageWithData:data];
} - 清除缓存的照片
[Objective-C] 纯文本查看 复制代码 - (void)clearLoopImageViewCaches
{
NSFileManager *managar = [NSFileManager defaultManager];
[managar removeItemAtPath:[self getLocationImageDataFilePath] error:nil];
} - 关键的步骤
[Objective-C] 纯文本查看 复制代码 // 获取照片 缓存有的话就从 缓存中去取到 否则网络请求
- (void)getImageUrlString:(NSString *)imageUrlStr delegate:(id<PP_LoadImageManagarDelegate>)dele successfulBlock:(PP_RturnBlock)returnImage
{
UIImage *image = [self getImageFromSubPath:imageUrlStr];
if (image)
{
// 6.代理执行协议中的方法,将图片作为参数传过去
dispatch_async(dispatch_get_main_queue(), ^{
dele != nil ? [dele imageDownloader:self didFinishedLoading:image] : nil;
// 6.用Block回调传递数据
returnImage != nil ? returnImage(image) : nil ;
});
}else
{
__weak typeof(PP_LoadImageManagar) * downloader = self;
//1.准备url对象
NSURL * url = [NSURL URLWithString:imageUrlStr];
//2.创建request请求对象
NSURLRequest * request = [NSURLRequest requestWithURL:url];
//3.创建会话
NSURLSession *session = [NSURLSession sharedSession];
//4.创建请求任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 获取数据写入本地
UIImage *image = nil;
if (!data)
{
image = [UIImage imageNamed:@"LoopImg.bundle/占位"];
}else
{
//5.将图片传值
image = [UIImage imageWithData:data];
[self writToCacheWithData:UIImageJPEGRepresentation(image, 1) subPath:imageUrlStr];
}
//6.代理执行协议中的方法,将图片作为参数传过去
dispatch_async(dispatch_get_main_queue(), ^{
dele != nil ? [dele imageDownloader:downloader didFinishedLoading:image] : nil;
// 6.用Block回调传递数据
returnImage != nil ? returnImage(image) : nil ;
});
}];
//执行任务
[task resume];
}
} Ps: 这是简单获取网址照片的方法简单实现,只需要在初始化轮播图的时候把需要展示的网址数组传入,同时传入一个参数让轮播图类明白这是网址照片。 最后在展示照片的地方判断是否需要调用我们创建的获取网络图片的类的方法后去图片。
[Objective-C] 纯文本查看 复制代码 /**
创建方法
@param imageArray 存放照片名称的数组
@param frame 位置
@param fromNetWork
*/
- (instancetype)initWithImageArray:(NSArray <NSString *>*)imageArray
fram:(CGRect)frame
fromNetWork:(BOOL)fromNetwork;
/**
更改图片数据的方法
@param newArray 新的数据数组 存储的是照片的信息
@param fromNetWork 是否是网络照片
*/
- (void)changeImageArray:(NSArray *)newArray fromNetWork:(BOOL)fromNetWork;
精华推荐: |
|