lazy loading images in UITableView iPhone SDK

删除回忆录丶 提交于 2019-12-20 03:16:09

问题


I need to implement the lazy loading concept for the images in my tableview, so that the user will be provided with the textual data initially and later the images.

How can i implement this in to my app.. help needed.. please

Thanks in advance

Shibin


回答1:


What i have created for a project of mine works as follows; Extend the UITableViewCell class by a category in "UITableViewCell+Async.h" (See some examples if you are not sure what the category thing in Obj C is)

@interface UITableViewCell (Async)

-(void)loadAsyncImage:(NSString*)url withIndex:(NSInteger)index inWidth:(NSInteger)width inHeight:(NSInteger)height;
-(void)loadAsyncBackground:(NSMutableArray*)parameters;

@end

And then in the implementation file "UITableViewCell+Async.m"

#import "UITableViewCell+Async.h"

@implementation UITableViewCell (Async)

-(void)loadAsyncImage:(NSString*)url 
            withIndex:(NSInteger)index 
              inWidth:(NSInteger)width 
             inHeight:(NSInteger)height {

    NSMutableArray* parameters = [NSMutableArray arrayWithCapacity:2];
    [parameters addObject:url];
    [parameters addObject:[NSNumber numberWithInteger:index]];
    [parameters addObject:[NSNumber numberWithInteger:width]];
    [parameters addObject:[NSNumber numberWithInteger:height]];

    self.imageView.tag = index;
    [self performSelectorInBackground:@selector(loadAsyncBackground:) withObject:parameters];

}

-(void)loadAsyncBackground:(NSMutableArray*)parameters {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString* url = [parameters objectAtIndex:0];
    NSInteger index = [[parameters objectAtIndex:1] integerValue];
    NSInteger width = [[parameters objectAtIndex:2] integerValue];
    NSInteger height = [[parameters objectAtIndex:3] integerValue];

    UIImage* image = [Utils getImageResized:url inSize:CGSizeMake(width, height)];

    if (self.tag==index) {
        self.imageView.image = image;
        [self setNeedsLayout];
    }

    [pool release];
}

@end

This basically adds a functionality to the UITableViewCell to load an image in a new background thread, resize the image and set it to the imageview. Checking the tag is added to see if the cell is still waiting for the image, since it can be re-used and another thread for the image could be downloading another image for that re-used cell...

The function in the above code with the signature of;

+(UIImage*)getImageResized:(NSString*)url inSize:(CGSize)size;

checks a local cache of images, downloads the image from the web if not in the cache, saves it to local cache, resizes the image in the given size and returns the image, all done in a sync(blocking) method call. Since this is already the background thread, no harm blocking it for this operation. When the method returns the image, it is set to the cell's imageview if it still has the same tag(not re-used for some other row)

In the cellForRowAtIndexPath method you can add the new category and you should be done;

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"......."];
    if (cell == nil) {
................
    }
................
    [cell loadAsyncImage:deal.logo withIndex:indexPath.row inWidth:40 inHeight:40];
................

    return cell;
}



回答2:


Do you mean this

http://developer.apple.com/iphone/library/samplecode/LazyTableImages/Introduction/Intro.html




回答3:


I used ASINetworkQueue for lazy loading.

In .h file

#import "ASINetworkQueue.h"

and define a variable

//array contains url address of images and a variable of ASINetworkQueue;
NSMutableArray *arrImg;
ASINetworkQueue *queue;

In .m file

static int rowNo = 0;
- (void)downloadImages{

    if(queue == nil){
        queue = [[[ASINetworkQueue alloc] init] autorelease];
    }

    for(NSString* urlString in arrImg)
    {
        NSURL *url = [NSURL URLWithString:urlString];
        ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
        [request setDelegate:self];
        [request setDidFinishSelector:@selector(requestDone:)];
        [request setDidFailSelector:@selector(requestWentWrong:)];
        [queue addOperation:request];
    }

    [queue go];

}


- (void)requestDone:(ASIHTTPRequest*)req{   

    for (int i = 0; i < [arrImg count]; i++) {

        NSMutableString *d = [[NSMutableString alloc] init];
        d = [arrImg objectAtIndex:i];

        //comparing the url to get correct row no of cell
        if([[req.url absoluteString] isEqualToString:d]){
            rowNo = i;
            break;
        }
    }

    //creating a cell with rowNo
    NSIndexPath *index = [NSIndexPath indexPathForRow:rowNo inSection:0];

    UITableViewCell *cell = (UITableViewCell *)[roomTable cellForRowAtIndexPath:index];

    UIImageView *v = (UIImageView *)[cell.contentView viewWithTag:10];

    v.image = [UIImage imageWithData:[req responseData]];

    [cell release];
    cell = nil;
    [v release];
    v = nil;
}

- (void)requestWentWrong:(ASIHTTPRequest*)req{

    for (int i = 0; i < [arrImg count]; i++) {

        NSMutableString *d = [[NSMutableString alloc] init];
        d = [arrImg objectAtIndex:i];

        //comparing the url to get correct row no of cell
        if([[req.url absoluteString] isEqualToString:d]){
            rowNo = i;
            break;
        }
    }
    NSLog(@"No data for cell : %d",rowNo);
    NSLog(@"Request returned an error %@",[req error]);
}


来源:https://stackoverflow.com/questions/2828312/lazy-loading-images-in-uitableview-iphone-sdk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!