异步加载 UIImageView

来源:互联网 发布:2016淘宝流量怎么提高 编辑:程序博客网 时间:2024/06/05 08:19

#import <UIKit/UIKit.h>
@interface AsyncImageView : UIView {
    //could instead be a subclass of UIImageView instead of UIView, depending on what other features you want to 
    // to build into this class?

    NSURLConnection* connection; //keep a reference to the connection so we can cancel download in dealloc
    NSMutableData* data; //keep reference to the data so we can collect it as it downloads
    //but where is the UIImage reference? We keep it in self.subviews - no need to re-code what we have in the parent class
    
}
- (void)loadImageFromURL:(NSURL*)url;
- (UIImage*) image;
@end

 

//
//  AsyncImageView.m
//  Postcard
//
//  Created by markj on 2/18/09.
//  Copyright 2009 Mark Johnson. You have permission to copy parts of this code into your own projects for any use.
//  www.markj.net
//

#import "AsyncImageView.h"


// This class demonstrates how the URL loading system can be used to make a UIView subclass
// that can download and display an image asynchronously so that the app doesn't block or freeze
// while the image is downloading. It works fine in a UITableView or other cases where there
// are multiple images being downloaded and displayed all at the same time. 

@implementation AsyncImageView

- (void)dealloc {
    [connection cancel]; //in case the URL is still downloading
    [connection release];
    [data release]; 
    [super dealloc];
}


- (void)loadImageFromURL:(NSURL*)url {
    if (connection!=nil) { [connection release]; } //in case we are downloading a 2nd image
    if (data!=nil) { [data release]; }
    
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //notice how delegate set to self object
    //TODO error handling, what if connection is nil?
}


//the URL connection calls this repeatedly as data arrives
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
    if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; } 
    [data appendData:incrementalData];
}

//the URL connection calls this once all the data has downloaded
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
    //so self data now has the complete image 
    [connection release];
    connection=nil;
    if ([[self subviews] count]>0) {
        //then this must be another image, the old one is still in subviews
        [[[self subviews] objectAtIndex:0] removeFromSuperview]; //so remove it (releases it also)
    }
    
    //make an image view for the image
    UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
    //make sizing choices based on your needs, experiment with these. maybe not all the calls below are needed.
    imageView.contentMode = UIViewContentModeScaleAspectFit;
    imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight );
    [self addSubview:imageView];
    imageView.frame = self.bounds;
    [imageView setNeedsLayout];
    [self setNeedsLayout];

    [data release]; //don't need this any more, its in the UIImageView now
    data=nil;
}

//just in case you want to get the image directly, here it is in subviews
- (UIImage*) image {
    UIImageView* iv = [[self subviews] objectAtIndex:0];
    return [iv image];
}

@end

原创粉丝点击