iOS开发中通过点击按钮异步加载图片
2015-09-17 19:49
676 查看
AsyncImageView.h:
#import
@interface AsyncImageView : UIView
{
NSURLConnection* connection;
NSMutableData* data;
}
- (void)loadImageFromURL:(NSURL*)url;
@end
AsyncImageView.m:
#import "AsyncImageView.h"
@implementation AsyncImageView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self) {
// Initialization code
}
returnself;
}
- (void)loadImageFromURL:(NSURL*)url {
if(connection!=nil) { [connection release]; }
if(data!=nil) { [data release]; }
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc]
initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)theConnection
didReceiveData:(NSData *)incrementalData {
if(data==nil) {
data =
[[NSMutableData alloc] initWithCapacity:2048];
}
[data appendData:incrementalData];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
[connection release];
connection=nil;
if([[self subviews] count] > 0) {
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight );
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
[data release];
data=nil;
}
- (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return[iv image];
}
- (void)dealloc {
[connection cancel];
[connection release];
[data release];
[super dealloc];
}
@end
方法二:
复制代码 代码如下:
@interface UIButton (AsyncImage)
//size by point
- (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage;
@end
@implementation UIButton (AsyncImage)
- (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
if (image) {
if (!CGSizeEqualToSize(size, CGSizeZero)) {
image = [UIImage imageWithCGImage:image.CGImage scale:[self scaleImage:image adjustToSize:size] orientation:image.imageOrientation];
}
if (logoImage) {
image = [self addLogoImage:logoImage toImage:image];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image forState:UIControlStateNormal];
completion();
});
}
else {
NSLog(@"async load error.");
}
});
}
// 缩放图片以适应按钮大小
- (CGFloat)scaleImage:(UIImage *)image adjustToSize:(CGSize)size
{
CGFloat xScale = size.width / image.size.width;
CGFloat yScale = size.height / image.size.height;
return 1.0 / MIN(xScale, yScale);
}
- (UIImage *)addLogoImage:(UIImage *)logo toImage:(UIImage *)img
{
//get image width and height
CGFloat scale = [UIScreen mainScreen].scale;
int w = scale * img.size.width;
int h = scale * img.size.height;
int logoWidth = logo.scale * logo.size.width;
int logoHeight = logo.scale * logo.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//create a graphic context with CGBitmapContextCreate
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextDrawImage(context, CGRectMake(w - logoWidth, 0, logoWidth, logoHeight), [logo CGImage]);
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked scale:scale orientation:img.imageOrientation];
}
@end
方法三:
?
实现文件:
?
#import
@interface AsyncImageView : UIView
{
NSURLConnection* connection;
NSMutableData* data;
}
- (void)loadImageFromURL:(NSURL*)url;
@end
AsyncImageView.m:
#import "AsyncImageView.h"
@implementation AsyncImageView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self) {
// Initialization code
}
returnself;
}
- (void)loadImageFromURL:(NSURL*)url {
if(connection!=nil) { [connection release]; }
if(data!=nil) { [data release]; }
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc]
initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)theConnection
didReceiveData:(NSData *)incrementalData {
if(data==nil) {
data =
[[NSMutableData alloc] initWithCapacity:2048];
}
[data appendData:incrementalData];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
[connection release];
connection=nil;
if([[self subviews] count] > 0) {
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight );
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
[data release];
data=nil;
}
- (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return[iv image];
}
- (void)dealloc {
[connection cancel];
[connection release];
[data release];
[super dealloc];
}
@end
方法二:
复制代码 代码如下:
@interface UIButton (AsyncImage)
//size by point
- (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage;
@end
@implementation UIButton (AsyncImage)
- (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
if (image) {
if (!CGSizeEqualToSize(size, CGSizeZero)) {
image = [UIImage imageWithCGImage:image.CGImage scale:[self scaleImage:image adjustToSize:size] orientation:image.imageOrientation];
}
if (logoImage) {
image = [self addLogoImage:logoImage toImage:image];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image forState:UIControlStateNormal];
completion();
});
}
else {
NSLog(@"async load error.");
}
});
}
// 缩放图片以适应按钮大小
- (CGFloat)scaleImage:(UIImage *)image adjustToSize:(CGSize)size
{
CGFloat xScale = size.width / image.size.width;
CGFloat yScale = size.height / image.size.height;
return 1.0 / MIN(xScale, yScale);
}
- (UIImage *)addLogoImage:(UIImage *)logo toImage:(UIImage *)img
{
//get image width and height
CGFloat scale = [UIScreen mainScreen].scale;
int w = scale * img.size.width;
int h = scale * img.size.height;
int logoWidth = logo.scale * logo.size.width;
int logoHeight = logo.scale * logo.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//create a graphic context with CGBitmapContextCreate
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextDrawImage(context, CGRectMake(w - logoWidth, 0, logoWidth, logoHeight), [logo CGImage]);
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked scale:scale orientation:img.imageOrientation];
}
@end
方法三:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #import <Foundation/Foundation.h> #import "StringUtils.h" @interface ImageManager : NSObject { NSMutableDictionary *_imageDict; NSMutableArray *_imageArr; } @property(nonatomic, strong) NSString *httpUrl; @property(nonatomic, strong) NSMutableDictionary *imageDict; @property(nonatomic, assign) dispatch_queue_t networkQueue; + (ImageManager *) sharedInstance; - (void)asyncImage:(NSString *)imageName imageView:(UIImageView *)imageView; //插队 - (void)asyncImageInsert:(NSString *)imageName imageView:(UIImageView *)imageView insert:(BOOL)insert; //不要在下载之前的数据 - (void)asyncImageCleanOld:(NSString *)imageName imageView:(UIImageView *)imageView cleanOld:(BOOL)cleanOld; @end |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | // // ImageManager.m // myb-ios // // Created by warrior gao on 13-6-5. // Copyright (c) 2013年 51myb. All rights reserved. // #import "ImageManager.h" @interface ImageManager() @end @implementation ImageManager //缓存图片的最大数量 static int counter = 0; @synthesize imageDict = _imageDict; //Singleton + (ImageManager *)sharedInstance { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = self.new; }); return instance; } - (id)init { if((self = [super init])) { self.networkQueue = dispatch_queue_create("com.warrior.network.image", nil); _imageDict = [[NSMutableDictionary alloc] init]; _imageArr = [[NSMutableArray alloc] init]; } return self; } - (NSString *) fileFullPath:(NSString *)fileName { NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *fileFullPath = [NSString stringWithFormat:@"%@/%@",cachePath,fileName]; return fileFullPath; } //不要在下载之前的数据 - (void)asyncImageCleanOld:(NSString *)imageName imageView:(UIImageView *)imageView cleanOld:(BOOL)cleanOld { if(cleanOld) { [_imageArr removeAllObjects]; } [self asyncImage:imageName imageView:imageView]; } //插队,优先 - (void)asyncImageInsert:(NSString *)imageName imageView:(UIImageView *)imageView insert:(BOOL)insert { if([StringUtils isEmpty:imageName]){ return; } NSData *data = [NSData dataWithContentsOfFile:[self fileFullPath:[imageName stringByReplacingOccurrencesOfString:@"/" withString:@"-"]]]; if(data == nil){ [_imageDict setValue:imageView forKey:imageName]; if(insert) { [_imageArr insertObject:imageName atIndex:0]; } else { [_imageArr addObject:imageName]; } [self cacheImage]; } else { [imageView setImage:[UIImage imageWithData:data]]; } } //正常,附加到后面 - (void)asyncImage:(NSString *)imageName imageView:(UIImageView *)imageView { [self asyncImageInsert:imageName imageView:imageView insert:NO]; } //异步缓存图片到本地,最多有两个线程 -(void)cacheImage { for (; counter < 2 && _imageArr.count > 0; counter++) { NSString *imageName = nil; @synchronized(self){ imageName = [[_imageArr objectAtIndex:0] copy]; [_imageArr removeObjectAtIndex:0]; } if(imageName == nil) continue; dispatch_async(self.networkQueue, ^{ NSLog(@"Starting: %@", imageName); UIImage *avatarImage = nil; NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",self.httpUrl, imageName]]; NSData *responseData = [NSData dataWithContentsOfURL:url]; if(responseData.length > 0) { [responseData writeToFile:[self fileFullPath:[imageName stringByReplacingOccurrencesOfString:@"/" withString:@"-"]] atomically:NO]; avatarImage = [UIImage imageWithData:responseData]; NSLog(@"Finishing: %@", imageName); if (avatarImage) { dispatch_async(dispatch_get_main_queue(), ^{ UIImageView *imageView = [_imageDict objectForKey:imageName]; if(imageView != nil && avatarImage != nil){ [imageView setImage:avatarImage]; } [_imageDict removeObjectForKey:imageName]; [imageName release]; }); } } counter--; [self cacheImage]; }); } } @end |
相关文章推荐
- 按右键另存图片只能存BMP
- photoshop去除图片上的水印
- ruby实现的一个异步文件下载HttpServer实例
- C#异步绑定数据实现方法
- upload上传单张图片
- 图片引发的溢出危机(图)
- 科学知识:同步、异步、阻塞和非阻塞区别
- 探讨Ajax中同步与异步之间的区别
- C#实现把彩色图片灰度化代码分享
- C#将图片和字节流互相转换并显示到页面上
- C#监控文件夹并自动给图片文件打水印的方法
- 纯CSS实现的当鼠标移上图片添加阴影效果代码
- C#中异步回调函数用法实例
- C#实现打开画图的同时载入图片、最大化显示画图窗体的方法
- 随鼠标移动的图片或文字特效代码
- CSS 图片横向排列实现代码
- C#实现将Email地址转成图片显示的方法
- 超级经典一套鼠标控制左右滚动图片带自动翻滚
- 用css实现图片垂直居中的使用技巧
- C++实现读取图片长度和宽度