在tableview中异步设置图像

时间:2015-06-04 00:33:46

标签: ios image asynchronous tableview

我有builtin cd使用自定义单元格。我最初设置的是从TableView方法

中的网址抓取图片
cellForRowAtIndexPath

但这让我的TableView滚动滞后。一旦我删除了图像提取,它滚动得很好,所以我知道这是我的问题。

我的问题是:如何异步获取此图像并将其设置在我的单元格中?是否有捷径可寻?谢谢!

4 个答案:

答案 0 :(得分:1)

步骤1:拥有包含图像的缓存。要么只是在内存中,要么在磁盘上更好。

步骤2:当您需要图像时,调用一个方法,该方法从缓存中返回图像,或返回默认图像并开始下载。

步骤3:下载完成后,将图像添加到缓存中。然后找出哪些行需要图像。重新加载重新加载图像的所有行。

下载应该使用GCD异步完成。我真的建议您将下载代码添加到单独的,可重用的方法中,以便您可以处理下载错误。即使你现在不做,你也会在以后做。

答案 1 :(得分:0)

dataWithContentsOfURL是一个同步方法,而不是异步,如 Apple Documents描述了。

  

此方法非常适合将data:// URL转换为NSData对象,也可用于同步读取短文件。如果您需要读取可能较大的文件,请使用inputStreamWithURL:打开流,然后一次读取一个文件。

为了异步加载图像,特别是在tableViewCell中,请尝试使用第三部分库SDWebImage

答案 2 :(得分:0)

在tableviews cellforindexpath

中使用此代码
 NSURLRequest *req =[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"yourimageurl.com"]];

[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if(!error){
        UIImage *image =[UIImage imageWithData:data];
        cell.thumbnailImageView.image = image;
    }
     else{
            //error
   }


}];

答案 3 :(得分:0)

  1. 创建UIImageView类文件(我将其命名为MJTableImageView)。
  2. MJTableImageView.h 文件

        @interface MJTableImageView : UIImageView< NSURLConnectionDelegate, NSURLConnectionDataDelegate >
    
        {
        NSMutableData *imageData ;
        long long expectedLength;
        NSURLConnection *currentConnection;
        NSString *File_name;
    
        }
        @property(nonatomic,readonly)UIActivityIndicatorView *loadingIndicator;
        @property(nonatomic)BOOL showLoadingIndicatorWhileLoading;
    
        -(void)setImageUrl:(NSURL *)imageUrl fileName:(NSString *)name;
    
        @end
    
    MJTableImageView.m 文件

    -(void)setImageUrl:(NSURL *)imageUrl fileName:(NSString *)name
    {
        // discard the previous connection
        if(currentConnection)
        {
            [currentConnection cancel];
        }
    
        File_name = name;
    
        //reset current image
        self.image = nil;
    
    
    //    if(_showLoadingIndicatorWhileLoading)
    //    {
            //show the loading indicator
    
            if(!_loadingIndicator)
            {
                CGFloat width = self.bounds.size.width*0.5;
    
                _loadingIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((self.bounds.size.width-width)/2, (self.bounds.size.height-width)/2, 25.0 , 25.0)];
                _loadingIndicator.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
                _loadingIndicator.layer.cornerRadius = width*0.1;
            }
            [self startLoadingIndicator];
    //    }
    
        // initialize the placeholder data
        imageData = [NSMutableData data];
    
    
        // start the connection
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:imageUrl];
        request.cachePolicy = NSURLRequestUseProtocolCachePolicy;
    
        currentConnection = [NSURLConnection connectionWithRequest:request delegate:self];
    
    
    
    }
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        //if the image view is reused in a table view for example to load another image  previous image is discarded
        if(connection != currentConnection)
        {
            [connection cancel];
            [self cleanUp];
            return;
        }
    
        // append new Data
        [imageData appendData:data];
    
    
    
        // show the partially loaded image
        self.image = [UIImage imageWithData:imageData];
    }
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        expectedLength = response.expectedContentLength;
    }
    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        // clean up
        [self cleanUp];
    
    }
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        // show the full image
        self.image = [UIImage imageWithData:imageData];
    
        NSString *filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", File_name];
        NSData *data = UIImagePNGRepresentation([UIImage imageWithData:imageData]);
        [data writeToFile:filename atomically:YES];
    
        // clean up
        [self cleanUp];
    }
    -(void)cleanUp
    {
        // clean up
        imageData = nil;
        [self stopLoadingIndicator];
    }
    -(void)startLoadingIndicator
    {
        if(!_loadingIndicator.superview)
        {
            [self addSubview:_loadingIndicator];
        }
        [_loadingIndicator startAnimating];
    }
    -(void)stopLoadingIndicator
    {
        if(_loadingIndicator.superview)
        {
            [_loadingIndicator removeFromSuperview];
        }
        [_loadingIndicator stopAnimating];
    }
    

    我正在使用StoryBoard,所以我将ImageClass(MJTableImageView)文件添加到UItableviewcell ImageView并为其设置标签号。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        NSDictionary *dict = [self.arr objectAtIndex:indexPath.row];
    
        UITableViewCell *cell = [self.MJTableView dequeueReusableCellWithIdentifier:@"MJImageCell"];
        if(cell == nil)
        {
    
        }
        UILabel *appName = (UILabel*)[cell.contentView viewWithTag:2];
        appName.text = [dict valueForKey:@"trackName"];
    
        MJTableImageView *imageview = (MJTableImageView *)[cell.contentView viewWithTag:1];
    
        NSString *url = [dict valueForKey:@"artworkUrl60"];
    
        NSString *filename = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@",[dict valueForKey:@"trackName"] ];
        NSData *data = [NSData dataWithContentsOfFile:filename];
        if(data)
        {
            imageview.image = [UIImage imageWithData:data];
        }
        else
        {
            [imageview setImageUrl:[NSURL URLWithString:url] fileName:[dict valueForKey:@"trackName"]];
        }
        return  cell;
    }
    

    有关详细信息,请参阅Github Project MJTableImageSwift它位于Swift中。