Asynchronously set images in tableview

前端 未结 4 1150
鱼传尺愫
鱼传尺愫 2020-12-22 12:27

I have a TableView using custom cells. I initially was setting grabbing an image from a URL in the cellForRowAtIndexPath method

- (         


        
4条回答
  •  一整个雨季
    2020-12-22 12:39

    1. Create UIImageView Class File (i named it to MJTableImageView).

    in MJTableImageView.h File

        @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
    

    in MJTableImageView.m File

    -(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];
    }
    

    I am using StoryBoard so i add ImageClass(MJTableImageView) file to UItableviewcell ImageView and set tag number to it.

    - (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;
    }
    

    For More details see Github Project MJTableImageSwift it is in Swift.

提交回复
热议问题