带有Json文件的UITableView,将图像加载到单元格消失

Posted

技术标签:

【中文标题】带有Json文件的UITableView,将图像加载到单元格消失【英文标题】:UITableView with Json file, loading images to cell disappear 【发布时间】:2013-03-15 03:16:16 【问题描述】:

我正在使用由以下机构提供的 asyncimageview 类:http://www.markj.net/iphone-asynchronous-table-image/

我从一个 json 文件中获取图像 url 并将每个图像加载到一个单元格中。

问题:

当我向上滚动并向下滚动到同一单元格时,图像会重新加载(消失并再次出现)。我无法弄清楚为什么图像不断重新加载?有没有人对我如何让它停止有建议或解决方案?提前致谢!

   // Asks the data source to return a cell to insert in a particular table view location

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



    //Gets the current news article
    NewsArticle *theCurrentArticle = [self.listofNewsArticles objectAtIndex:[indexPath row]];

    //Gets the title from the current article
    NSString *theTitle = theCurrentArticle.title;

    //Gets the image url 
    NSString *imageUrl = theCurrentArticle.imageURL;

    //Gets the description of the current news article
    NSString *theDescription = theCurrentArticle.description;


    NewsCustomCell *cell = (NewsCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"NewsContent"];

    __block NewsCustomCell *aCell;

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^

    if (cell == nil) 
        aCell = (NewsCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"NewsContent"];
     else 
        AsyncImageView* oldImage = (AsyncImageView*)
        [cell.contentView viewWithTag:999];
        [oldImage removeFromSuperview];
    



    AsyncImageView *imageView = [[AsyncImageView alloc] initWithFrame:CGRectMake(5, 5, 100, 100)];
    imageView.tag = 999;

          dispatch_async(dispatch_get_main_queue(), ^
    [imageView loadImageFromURL:[NSURL URLWithString:imageUrl]];
    [cell.contentView addSubview:imageView];

              cell.titleLabel.text = theTitle;
              cell.descriptionLabel.text = theDescription;
              cell.imageLabel.contentMode = UIViewContentModeScaleAspectFill;

);

         );



    return cell;




以下是当前应用的外观:

解决办法:

刚刚与我终于找到的这门课一起工作。 https://github.com/rs/SDWebImage 这处理缓存、异步下载。希望我早点找到这个..

【问题讨论】:

听起来你所有的图像都有标签 999。如果你把这个标签做成独一无二的呢?就像每行索引路径的序列化版本一样? 嗯,我需要在那里标记,所以如果它检测到视图中已经存在图像,它会将其从超级视图中删除。这样您就不会让图像相互重叠。 【参考方案1】:

我希望你有写 AsyncImageView 和 ImageCache 和 ImageCacheObject 类。 在 cellForRowAtIndexPath 中写下这段代码:

    static NSString *CellIdentifier = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    
    Quest_Forum *Quest_ForumObj=[queArr objectAtIndex:i+indexPath.row];
  //  NSLog(@"cell for row at... i val.. %d",i+indexPath.row);

    for(UIView * view in cell.contentView.subviews)
        if([view isKindOfClass:[AsyncImageView class]])
        
           // NSLog(@"remove old images");
            [view removeFromSuperview];
            view = nil;
        
    

    AsyncImageView *asyncImageView = nil;

    UIImageView *cellImage = (UIImageView *)[cell viewWithTag:1]; // Inside tableview i have taken tableviewcell and given tag 1 to that imageview

    asyncImageView = [[AsyncImageView alloc] initWithFrame:cellImage.frame] ;
    [asyncImageView loadImageFromURL:Quest_ForumObj.Quest_Image];
    asyncImageView.backgroundColor=[UIColor clearColor]; 
    [cell.contentView addSubview:asyncImageView];


    UILabel *lblQuest = (UILabel *)[cell viewWithTag:2]; // Given tag 2 to the label inside tableViewCell
    lblQuest.text=Quest_ForumObj.Question;

在 ImageCacheObject.h 中

@class ImageCacheObject;

@interface ImageCache : NSObject 

    NSUInteger totalSize;  // total number of bytes
    NSUInteger maxSize;    // maximum capacity
    NSMutableDictionary *myDictionary;


@property (nonatomic, readonly) NSUInteger totalSize;

-(id)initWithMaxSize:(NSUInteger) max;
-(void)insertImage:(UIImage*)image withSize:(NSUInteger)sz forKey:(NSString*)key;
-(UIImage*)imageForKey:(NSString*)key;

在 ImageCacheObject.m 中

#import "ImageCacheObject.h"

@synthesize totalSize;

-(id)initWithMaxSize:(NSUInteger) max  

    if (self = [super init]) 
    
        totalSize = 0;
        maxSize = max;
        myDictionary = [[NSMutableDictionary alloc] init];
    
    return self;


-(void)dealloc // Don't write this method if you are using ARC 

    [myDictionary release];
    [super dealloc];


-(void)insertImage:(UIImage*)image withSize:(NSUInteger)sz forKey:(NSString*)key

   // NSLog(@"count of insert image%d",sz);
    ImageCacheObject *object = [[ImageCacheObject alloc] initWithSize:sz Image:image];
    while (totalSize + sz > maxSize) 
    
        NSDate *oldestTime;
        NSString *oldestKey;
        for (NSString *key in [myDictionary allKeys]) 
        
            ImageCacheObject *obj = [myDictionary objectForKey:key];
            if (oldestTime == nil || [obj.timeStamp compare:oldestTime] == NSOrderedAscending) 
            
                oldestTime = obj.timeStamp;
                oldestKey = key;
            
        
        if (oldestKey == nil) 
            break; // shoudn't happen
        ImageCacheObject *obj = [myDictionary objectForKey:oldestKey];
        totalSize -= obj.size;
        [myDictionary removeObjectForKey:oldestKey];
    
    [myDictionary setObject:object forKey:key];
    [object release];


-(UIImage*)imageForKey:(NSString*)key 

    ImageCacheObject *object = [myDictionary objectForKey:key];
    if (object == nil)
        return nil;
    [object resetTimeStamp];
    return object.image;

在 ImageCacheObject.h 中

@interface ImageCacheObject : NSObject 

    NSUInteger size;    // size in bytes of image data
    NSDate *timeStamp;  // time of last access
    UIImage *image;     // cached image


@property (nonatomic, readonly) NSUInteger size;
@property (nonatomic, retain, readonly) NSDate *timeStamp;
@property (nonatomic, retain, readonly) UIImage *image;

-(id)initWithSize:(NSUInteger)sz Image:(UIImage*)anImage;
-(void)resetTimeStamp;

在 ImageCacheObject.m 中

@synthesize size;
@synthesize timeStamp;
@synthesize image;

-(id)initWithSize:(NSUInteger)sz Image:(UIImage*)anImage

    if (self = [super init]) 
    
        size = sz;
        timeStamp = [[NSDate date] retain];
        image = [anImage retain];
    
    return self;


-(void)resetTimeStamp 

    [timeStamp release];
    timeStamp = [[NSDate date] retain];


-(void) dealloc 

    [timeStamp release];
    [image release];
    [super dealloc];

【讨论】:

不,我没有图像缓存或图像缓存对象。 :/你能指点我一些来源吗?我也会四处看看。谢谢! 嗨,Shah,感谢您的帮助!今天早上我真的尝试过使用 imageCache,但后来发现 github.com/rs/SDWebImage 可以很好地处理所有这些。谢谢你的回复,虽然我很感激!

以上是关于带有Json文件的UITableView,将图像加载到单元格消失的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UITableView 的背景设置为图像?

从 AFNetworking 2.0 加载带有 JSON 的 UITableView

使用 Json 图像 URL 调用 swift 填充 UITableView

UITableView - 带有背景图像的 UIRefreshControl

我们是不是应该在将图像设置为 UITableView 中的 imageView 之前缩放图像

JSON & Xcode 6 UITableView