从服务器加载图像之前加载“加载”图像?

时间:2012-04-26 18:07:40

标签: ios xcode multithreading ipad photo-gallery

我是iOS开发的新手,所以请耐心等待。 我正在尝试创建一个基本的照片库,但遇到了一个问题。 当我开始使用该项目时,我只是在项目中包含了所有图像。 现在有了更多的图像(400+)后,我开始从服务器加载它们。 我使用以下代码行制作了一系列图像:

[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.testsite.com/testPic.png"]]]

显然,让用户等待从服务器加载400多个图像的数组是不可接受的。

所以我的问题是,如果我在项目中包含一个类似“正在加载”的图像,那么在从服务器加载实际图像之前,我该如何显示该图像呢?

我正在使用表视图和滚动视图制作基本的网格式照片库。它会加载几行小(缩略图)图像,当您单击一行时,它会全屏显示。

如果有帮助,我正在使用Xcode 4.3,ARC和故事板!

对不起,如果这令人困惑!

-Shredder2794

2 个答案:

答案 0 :(得分:1)

方法是子类UIImageView。当您分配它时,您放置一个默认图像(加载一个)或UIActivityIndicator,下载您想要显示的图像(在一个单独的线程中),并在下载图像时显示它。请查看NSURLRequestNSURLConnection以获取图片下载。

*编辑*

以下是我开发的代码示例。您可以将其用作开发自己的加载图像类的起点。通过使用NSThread进行图像加载,可以改进此类。

// ImageLoader.h


#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

/**
 *  @brief  Class that loads an UIImage from a server
 *  @author Nicolas
 */
@interface ImageLoader : UIView 
{
    @private
    NSURLConnection         *connection;
    NSMutableData           *data;
    NSString                *path;
    UIActivityIndicatorView *loading;
    UIImageView             *imageView;
}

@property (nonatomic, retain) UIActivityIndicatorView   *loading;
@property (nonatomic, retain) NSURLConnection           *connection;
@property (nonatomic, retain) NSMutableData             *data;
@property (nonatomic, retain) NSString                  *path;
@property (nonatomic, retain) UIImageView               *imageView;

/**
 *  Load an image from a server an display it
 *  @param URL URL to get the image
 *  @param chemin path to save the image
 *  @author Nicolas
 */
- (void)loadImageFromUrl:(NSString *)URL forPath:(NSString *)chemin;

@end



// ImageLoader.m


#import "ImageLoader.h"


@implementation ImageLoader
@synthesize path, connection, data, loading, imageView;

- (id)init
{
    self = [super init];
    [self setUserInteractionEnabled:YES];
    return self;
}

- (void)loadImageFromUrl:(NSString *)URL forPath:(NSString *)chemin
{
    //if (connection != nil)    [connection release];
    //if (data !=  nil)     [data release];
    //if (path != nil)      [path release];

    self.path = chemin;

    if ([[NSFileManager defaultManager] fileExistsAtPath:chemin])
    {
        if (imageView != nil)
        {
            [imageView removeFromSuperview];
            [imageView release];
        }
        imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        imageView.image = [UIImage imageWithContentsOfFile:chemin];
        [self addSubview:imageView];
    }
    else 
    {
        loading = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20.0f, 20.0f)];
        loading.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
        [loading setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
        [loading startAnimating];
        [self addSubview:loading];

        NSURL *myURL = [NSURL URLWithString:[URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];      
        NSURLRequest *request = [NSURLRequest requestWithURL:myURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0f];
        connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    }
}

#pragma mark -
#pragma mark NSURLConnection protocol

- (void)connection:(NSURLConnection *)_connection didReceiveData:(NSData *)_data
{
    if (data == nil)
    {
        data = [[NSMutableData alloc] initWithCapacity:2048];
    }
    [data appendData:_data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)_connection
{
    [data writeToFile:self.path atomically:YES];

    if (imageView != nil)
    {
        [imageView removeFromSuperview];
        [imageView release];
    }

    imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:data]];
    imageView.frame = self.bounds;
    imageView.contentMode = UIViewContentModeScaleAspectFit;
    imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    [loading stopAnimating];
    [loading setHidden:YES];
    [self addSubview:imageView];
}

- (void)connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error
{
    [loading stopAnimating];
    [loading release];
}

#pragma mark - Memory management

- (void)dealloc
{
    [connection cancel];
    [connection release];
    [imageView release];
    [path release];
    [data release];
    [super dealloc];
}

@end

答案 1 :(得分:1)

最简单的方法是使用AFNetworkingsetImageWithURL:placeholderImage:UIImageView的类别中提供{{1}}(也是成功/失败处理程序的方法)。