带有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,将图像加载到单元格消失的主要内容,如果未能解决你的问题,请参考以下文章
从 AFNetworking 2.0 加载带有 JSON 的 UITableView
使用 Json 图像 URL 调用 swift 填充 UITableView
UITableView - 带有背景图像的 UIRefreshControl