ios通过按钮点击异步加载图片
程序员文章站
2022-06-09 19:45:26
比较原始的方法:
复制代码 代码如下:
asyncimageview.h:
#import
@interface asy...
比较原始的方法:
复制代码 代码如下:
asyncimageview.h:
#import <uikit/uikit.h>
@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 <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
实现文件:
// // 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
以上所述就是本文的全部内容 了,希望大家能够喜欢。
上一篇: 关于在VM上安装RAC ASM UDEV 无法返回UUID 问题
下一篇: ios触屏事件指南