当前位置: 移动技术网 > 移动技术>移动开发>IOS > ios通过按钮点击异步加载图片

ios通过按钮点击异步加载图片

2019年07月24日  | 移动技术网移动技术  | 我要评论

比较原始的方法:

复制代码 代码如下:

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

以上所述就是本文的全部内容 了,希望大家能够喜欢。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网