如何加载带有一些默认图像的表,直到它从互联网 iPhone 获取原始图像?

发布于 2024-11-24 07:16:37 字数 159 浏览 1 评论 0原文

我有一个 uitableview 将一张图像存储在一个单元格中。它的图像是从互联网加载的。问题是应用程序变得很慢,直到从互联网加载其图像为止。所以我想设置一种机制,它首先加载默认图像,当它获取原始图像时,默认图像将被原始图像替换。

给我任何教程或任何示例代码。

提前致谢。

I have a uitableview which stores one image in one cell. Its image get loaded from internet. The problem is the application get slow till its image get loaded from internet. So I want to put a mechanism that it first get loaded with a default image and when it gets the original then the default image will be replaced by the original one.

Give me any tutorial or any sample code for it.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

找回味觉 2024-12-01 07:16:39

通过其他线程获取图像...并使用通知或委托来跟踪图像下载中的任何更改...假设您正在使用通知...然后在您设置为该通知的观察者的类中重新加载tableView 的数据 .... 因此您的表格图像将在默认图像的位置进行更新 .... 有关更多详细信息,让我们举个例子 ..... 创建一个操作类来下载我们称之为拇指的图像 .. ..在这个例子中我做了两个类
1. PhotoGalleryVC 显示拇指列表以及每个拇指的一些详细信息
2. LoadGalleryThumbOp [Op = 操作] 在 LoadGalleryThumbOp.m 中完成后下载拇指并发布通知,

@protocol LoadGalleryThumbDelegate;
@interface LoadGalleryThumbOp : NSObject{

    NSIndexPath* indexPathInTableView;
    id <LoadGalleryThumbDelegate> delegate;
    NSMutableData *activeDownload;
        NSURLConnection *imageConnection;
    NSString * documentPath;
    BOOL imageDownload;
}
@property (nonatomic, assign) NSIndexPath* indexPathInTableView;
@property (nonatomic, retain) NSMutableData *activeDownload;
@property (nonatomic, retain) NSURLConnection *imageConnection;
@property (nonatomic, assign) id <LoadGalleryThumbDelegate> delegate;
@property (nonatomic, retain) NSString * documentPath;
@property (nonatomic) BOOL imageDownload;
- (void)startDownload;
- (void)cancelDownload;
- (void) persistData:(NSData*) data;
@end

@protocol LoadGalleryThumbDelegate 

- (void)appImageDidLoad:(NSIndexPath *)indexPath;

@end

因为

@implementation LoadGalleryThumbOp

@synthesize year;
@synthesize indexPathInTableView;
@synthesize delegate;
@synthesize activeDownload;
@synthesize imageConnection,documentPath,imageDownload;

#pragma mark

- (void)startDownload
{
    self.imageDownload = YES;
    self.activeDownload = [NSMutableData data];
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"images/thumb.jpg"]];
    if ([fm fileExistsAtPath:galleryDocumentPath]) 
    {
        UIImage *image = [[UIImage alloc] initWithContentsOfFile:galleryDocumentPath ];
         self.gallery.thumpImage = image;
        self.activeDownload = nil;
        [image release];
        self.imageConnection = nil;
         [delegate appImageDidLoad:self.indexPathInTableView];
    }
    else {
        NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
                                 [NSURLRequest requestWithURL:
                              [NSURL URLWithString:#error yourImageUrl]] delegate:self];
        self.imageConnection = conn;
        [conn release];
    }
}

- (void)cancelDownload
{
    [self.imageConnection cancel];
    self.imageConnection = nil;
    self.activeDownload = nil;
}


#pragma mark -
#pragma mark Download support (NSURLConnectionDelegate)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.activeDownload appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    self.activeDownload = nil;
    self.imageConnection = nil;
    self.imageDownload = NO;
     [NSString stringWithFormat:@"images/thumb.jpg"]];
    [delegate appImageDidLoad:self.indexPathInTableView];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self persistData:self.activeDownload];    
    self.activeDownload = nil;
    self.imageConnection = nil;
    [delegate appImageDidLoad:self.indexPathInTableView];
}
- (void) persistData:(NSData*) data
{
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"images/thumb.jpg"]];
    if ([[NSFileManager defaultManager] fileExistsAtPath:galleryDocumentPath]) 
    {
        NSError* err = nil;
        [fm removeItemAtPath:galleryDocumentPath error:&err];
        if (err)
            NSLog(@"%s:%@",__FUNCTION__,err);
    }
    [fm createFileAtPath:galleryDocumentPath contents:data attributes:nil];
}

此类将下载您想要的图像,并在下载图像时调用其委托。
使用它

@interface PhotoGalleryVC : UIViewController <LoadGalleryThumbDelegate>{

    IBOutlet UITableView* albumListTableView;
    NSMutableDictionary *imageDownloadsInProgress;
    NSArray* allThumbs;
}
@property (nonatomic, retain) NSMutableDictionary *imageDownloadsInProgress;

- (void)appImageDidLoad:(NSIndexPath *)indexPath;
@end

现在是 PhotoGalleryVC 中的使用部分,在 .m 部分中

- (void)viewDidLoad {
     self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
     .....

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath =  [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery/%@/images/thumb.jpg",[someObj.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ]]];
//this above line is just make a seperate folder for each object and store thumbs of that object in that folder ... so make it unique some how
    if (![fm fileExistsAtPath:galleryDocumentPath]) 
    {
        LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
        if (galleryThumbDownloader != nil && galleryThumbDownloader.imageDownload == NO)
        {
            [cell.activityIndicator stopAnimating];
            cell.albumCoverImageView.image = [UIImage imageNamed:@"no_thumb.png"];
        }
        else {
            [cell.activityIndicator startAnimating];                
        }
        [self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:@"%d",selectedYear]];
    }
    else
    {
        [cell.activityIndicator stopAnimating];
        cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
    }
    return cell ;
}

//The following method see if there is already so downloader that is downloading same image then it simply do nothing else it create a downloader and start it     
- (void)startIconDownload:(Gallery *)gallery forIndexPath:(NSIndexPath *)indexPath  andYear:(NSString*)yr
{
    LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
    if (galleryThumbDownloader == nil) 
    {
        NSString* documentsPath =    [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString* nameWithoutSpace = [gallery.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ];
        NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery//%@",nameWithoutSpace]];

        galleryThumbDownloader = [[LoadGalleryThumbOp alloc] init];
        galleryThumbDownloader.documentPath = galleryDocumentPath;
        galleryThumbDownloader.indexPathInTableView = indexPath;
        galleryThumbDownloader.delegate = self;
        [imageDownloadsInProgress setObject:galleryThumbDownloader forKey:indexPath];
        [galleryThumbDownloader startDownload];
        [galleryThumbDownloader release];   
    }
    else if(galleryThumbDownloader.imageDownload == NO)
    {
        if (albumListTableView.dragging || albumListTableView.decelerating) {
            [galleryThumbDownloader startDownload];
        }
    }
}

,最后是下载特定图像时调用的方法

- (void)appImageDidLoad:(NSIndexPath *)indexPath
{
    CustomCellPhotoGalary* cell = (CustomCellPhotoGalary*)[albumListTableView cellForRowAtIndexPath:indexPath];
    LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];

    if (galleryThumbDownloader != nil)
    {
        if (galleryThumbDownloader.imageDownload) 
        {
            [cell.activityIndicator stopAnimating];
            NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];                                
                    NSString* nameWithoutSpace = [temp.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ];
            NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery/%@",nameWithoutSpace]];
            cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
            //galleryThumbDownloader = nil;
        }
        else {
            [cell.activityIndicator stopAnimating];
            cell.albumCoverImageView.image = [UIImage imageNamed:@"no_thumb.png"];
            [self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:@"%d",selectedYear]];
    }
        [albumListTableView reloadData];
    }
}

woooh.....!一个例子有很多代码
注意:我删掉了很多行,所以这段代码可能无法直接为你工作{可能有很多错误..},但我希望你能了解幕后的主要思想...:)

Get your image trough some other thread .... and use notification or delegate to keep track of any change in image download ... suppose you are using notification .... then in class which you set as observer for that notification reload the data of tableView .... so your table image will get updated where there was so default image .... for more detail lets take an example ..... Make a operation class to downloading the image we call it thumb .... In this example I make 2 classes
1. PhotoGalleryVC which shows a list of thumbs and some detail of each thumb and
2. LoadGalleryThumbOp [Op = operation] downloads thumbs and post notification when done

@protocol LoadGalleryThumbDelegate;
@interface LoadGalleryThumbOp : NSObject{

    NSIndexPath* indexPathInTableView;
    id <LoadGalleryThumbDelegate> delegate;
    NSMutableData *activeDownload;
        NSURLConnection *imageConnection;
    NSString * documentPath;
    BOOL imageDownload;
}
@property (nonatomic, assign) NSIndexPath* indexPathInTableView;
@property (nonatomic, retain) NSMutableData *activeDownload;
@property (nonatomic, retain) NSURLConnection *imageConnection;
@property (nonatomic, assign) id <LoadGalleryThumbDelegate> delegate;
@property (nonatomic, retain) NSString * documentPath;
@property (nonatomic) BOOL imageDownload;
- (void)startDownload;
- (void)cancelDownload;
- (void) persistData:(NSData*) data;
@end

@protocol LoadGalleryThumbDelegate 

- (void)appImageDidLoad:(NSIndexPath *)indexPath;

@end

in LoadGalleryThumbOp.m do it as

@implementation LoadGalleryThumbOp

@synthesize year;
@synthesize indexPathInTableView;
@synthesize delegate;
@synthesize activeDownload;
@synthesize imageConnection,documentPath,imageDownload;

#pragma mark

- (void)startDownload
{
    self.imageDownload = YES;
    self.activeDownload = [NSMutableData data];
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"images/thumb.jpg"]];
    if ([fm fileExistsAtPath:galleryDocumentPath]) 
    {
        UIImage *image = [[UIImage alloc] initWithContentsOfFile:galleryDocumentPath ];
         self.gallery.thumpImage = image;
        self.activeDownload = nil;
        [image release];
        self.imageConnection = nil;
         [delegate appImageDidLoad:self.indexPathInTableView];
    }
    else {
        NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
                                 [NSURLRequest requestWithURL:
                              [NSURL URLWithString:#error yourImageUrl]] delegate:self];
        self.imageConnection = conn;
        [conn release];
    }
}

- (void)cancelDownload
{
    [self.imageConnection cancel];
    self.imageConnection = nil;
    self.activeDownload = nil;
}


#pragma mark -
#pragma mark Download support (NSURLConnectionDelegate)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.activeDownload appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    self.activeDownload = nil;
    self.imageConnection = nil;
    self.imageDownload = NO;
     [NSString stringWithFormat:@"images/thumb.jpg"]];
    [delegate appImageDidLoad:self.indexPathInTableView];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self persistData:self.activeDownload];    
    self.activeDownload = nil;
    self.imageConnection = nil;
    [delegate appImageDidLoad:self.indexPathInTableView];
}
- (void) persistData:(NSData*) data
{
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath = [self.documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"images/thumb.jpg"]];
    if ([[NSFileManager defaultManager] fileExistsAtPath:galleryDocumentPath]) 
    {
        NSError* err = nil;
        [fm removeItemAtPath:galleryDocumentPath error:&err];
        if (err)
            NSLog(@"%s:%@",__FUNCTION__,err);
    }
    [fm createFileAtPath:galleryDocumentPath contents:data attributes:nil];
}

this class will download the image you wanted and will call its delegate when the image is download ..
Now comes its use part in PhotoGalleryVC use it like this

@interface PhotoGalleryVC : UIViewController <LoadGalleryThumbDelegate>{

    IBOutlet UITableView* albumListTableView;
    NSMutableDictionary *imageDownloadsInProgress;
    NSArray* allThumbs;
}
@property (nonatomic, retain) NSMutableDictionary *imageDownloadsInProgress;

- (void)appImageDidLoad:(NSIndexPath *)indexPath;
@end

in .m part

- (void)viewDidLoad {
     self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
     .....

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

NSFileManager* fm = [NSFileManager defaultManager];
    NSString* galleryDocumentPath =  [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery/%@/images/thumb.jpg",[someObj.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ]]];
//this above line is just make a seperate folder for each object and store thumbs of that object in that folder ... so make it unique some how
    if (![fm fileExistsAtPath:galleryDocumentPath]) 
    {
        LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
        if (galleryThumbDownloader != nil && galleryThumbDownloader.imageDownload == NO)
        {
            [cell.activityIndicator stopAnimating];
            cell.albumCoverImageView.image = [UIImage imageNamed:@"no_thumb.png"];
        }
        else {
            [cell.activityIndicator startAnimating];                
        }
        [self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:@"%d",selectedYear]];
    }
    else
    {
        [cell.activityIndicator stopAnimating];
        cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
    }
    return cell ;
}

//The following method see if there is already so downloader that is downloading same image then it simply do nothing else it create a downloader and start it     
- (void)startIconDownload:(Gallery *)gallery forIndexPath:(NSIndexPath *)indexPath  andYear:(NSString*)yr
{
    LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];
    if (galleryThumbDownloader == nil) 
    {
        NSString* documentsPath =    [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString* nameWithoutSpace = [gallery.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ];
        NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery//%@",nameWithoutSpace]];

        galleryThumbDownloader = [[LoadGalleryThumbOp alloc] init];
        galleryThumbDownloader.documentPath = galleryDocumentPath;
        galleryThumbDownloader.indexPathInTableView = indexPath;
        galleryThumbDownloader.delegate = self;
        [imageDownloadsInProgress setObject:galleryThumbDownloader forKey:indexPath];
        [galleryThumbDownloader startDownload];
        [galleryThumbDownloader release];   
    }
    else if(galleryThumbDownloader.imageDownload == NO)
    {
        if (albumListTableView.dragging || albumListTableView.decelerating) {
            [galleryThumbDownloader startDownload];
        }
    }
}

finally the method which is called when a particular image is downloaded

- (void)appImageDidLoad:(NSIndexPath *)indexPath
{
    CustomCellPhotoGalary* cell = (CustomCellPhotoGalary*)[albumListTableView cellForRowAtIndexPath:indexPath];
    LoadGalleryThumbOp *galleryThumbDownloader = [imageDownloadsInProgress objectForKey:indexPath];

    if (galleryThumbDownloader != nil)
    {
        if (galleryThumbDownloader.imageDownload) 
        {
            [cell.activityIndicator stopAnimating];
            NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];                                
                    NSString* nameWithoutSpace = [temp.title stringByReplacingOccurrencesOfString:@" " withString:@"_" ];
            NSString* galleryDocumentPath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"Gallery/%@",nameWithoutSpace]];
            cell.albumCoverImageView.image = [UIImage imageWithContentsOfFile:galleryDocumentPath];
            //galleryThumbDownloader = nil;
        }
        else {
            [cell.activityIndicator stopAnimating];
            cell.albumCoverImageView.image = [UIImage imageNamed:@"no_thumb.png"];
            [self startIconDownload:temp forIndexPath:indexPath andYear:[NSString stringWithFormat:@"%d",selectedYear]];
    }
        [albumListTableView reloadData];
    }
}

woooh.....! thats a lot of code for one example
Note : I cut out so many line so this code may not work for u directly {there may be so many errors .. }, But i hope you get the main idea behind the scene ... :)

梦与时光遇 2024-12-01 07:16:39

这个示例代码很棒,它教会了我很多。
这使用了 ASIHttpRequest 框架,如果您要使用此技术,我建议您使用此处,因为示例代码中的版本现在已经很旧了。

此示例代码应该可以帮助您自定义单元格的委派等。

This sample code is great, It taught me a lot.
This uses the ASIHttpRequest framework, if you are going to use this technique, I recommend you use the latest version from here, because the version in the sample code is quite old now.

This sample code should help you with custom delegation of your cells etc.

红焚 2024-12-01 07:16:39

根据上述情况,使用 LazyTableImages 总是更好。

此处给出的最佳示例

As per above scenario, its always better to use LazyTableImages.

The best example given here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文