Created
July 20, 2009 04:55
-
-
Save naokits/150167 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AsyncImageView.h | |
// 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 | |
// | |
// See | |
// http://www.markj.net/iphone-asynchronous-table-image/ | |
// http://blogs.oreilly.com/iphone/2008/12/useful-core-graphics-functions.html | |
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment